flux changed the topic of #ocaml to: Discussions about the OCaml programming language | http://caml.inria.fr/ | 3.11.0 out now! Get yours from http://caml.inria.fr/ocaml/release.html
Mr_Awesome has joined #ocaml
pina has joined #ocaml
pina has left #ocaml []
slash_ has quit [Client Quit]
dejj has quit ["Leaving..."]
Guest44514 has quit [Remote closed the connection]
Amorphous has quit [Read error: 145 (Connection timed out)]
Smerdyakov has quit ["Leaving"]
Amorphous has joined #ocaml
alexyk has joined #ocaml
<alexyk> I need to count ranges in sequences, so am thinking of Hashtbl of dynarrays -- for each int list as a key, I'll need to keep a list of where it's encountered; those lists can grow long; so I'm thinking of Hashtbl with an int list key and dynarray of tuples as value. Is it a good solution? Are there other ways to efficiently grow Hashtbl of long values?
alexyk has quit []
alexyk has joined #ocaml
seafood has joined #ocaml
alexyk has quit []
alexyk has joined #ocaml
alexyk has quit [Client Quit]
alexyk has joined #ocaml
jumpnotzero has joined #ocaml
seafood has quit []
jumpnotzero has quit ["leaving"]
alexyk has quit []
malc_ has joined #ocaml
seafood has joined #ocaml
malc_ has quit ["leaving"]
seafood has quit []
m3ga has joined #ocaml
m3ga has quit [Read error: 104 (Connection reset by peer)]
mattam has quit ["Lost terminal"]
seafood has joined #ocaml
shortc|desk has quit ["Probably rebooting."]
shortc|desk has joined #ocaml
m3ga has joined #ocaml
fschwidom has joined #ocaml
m3ga has quit ["disappearing into the sunset"]
<mrvn> gildor: It is not really a bug. More a feature request.
<mrvn> gildor: In a broader sense the finalizer is about freeing resources and some resources might not be freed on exit if the finalizer is not run.
seafood has quit []
<gildor> mrvn: have you read my message on ocaml debian mailing list ?
<gildor> mrvn: it gives you more reasons why I think putting your "other than memory resource" deallocation in finalizer is a bad idea
<gildor> though it is a good place to warn that something has not been freed
<gildor> but people should have other way to deallocate/ensure end of operation than finalize
<gildor> which they cannot control
Kerris7 has joined #ocaml
<gildor> (I mean calling finalize is up to the Gc, not the user/programmer)
Kerris7 has quit [Read error: 54 (Connection reset by peer)]
Kerris7 has joined #ocaml
Kerris7 has left #ocaml []
<mrvn> gildor: reading currently
<mrvn> gildor: I feel that ensuring no resource is ever closed too early or forgotten forever is more important than saying precisly when it will be freed. That is the price I pay for using a GC.
<mrvn> Plus it is only a few k so big deal if it lingers a few minutes.
<gildor> mrvn: a GC is about memory, not file descriptor
<gildor> mrvn: why do you think there is a close_out function for channel
<mrvn> I don't have a file descriptor here. Just some struct iocbs.
<gildor> I know aio
<gildor> but when you say that it can wait "a few minutes"
<gildor> you are just betting that the GC will do its job in a few minutes
<gildor> which is totally false
<mrvn> it will run eventually. Except when the program exits.
<gildor> the GC can free your structure from "a few seconds" to a "few hours"
<gildor> do you really think this is the way people will use your library ?
<gildor> waiting a few hours to be sure that the data has been written ?
<mrvn> I doubt verry many will use it for short periods. The normal case will be to open it at start and use it till the end.
<gildor> not getting the error status of the last operation ?
<gildor> mrvn: to be serious, if you come to INRIA OCaml team with such an argument, I really doubt they will even try to implement it
<mrvn> gildor: You call "AIO.run ctx" to wait for events to complete. That is the normal way.
<mrvn> The problem comes when you forget to wait for an event to finish by accident. What then?
<gildor> if its the normal way, lets do its this way
<gildor> that is the point I was talking above: output an error message but don't do the job
<gildor> forgetting to wait about an event is a programming error
<mrvn> gildor: How? _finalized is not called so it can't give an error.
<mrvn> The program just quits and data will be lost.
<gildor> indeed
<gildor> don't try to recover your lost data
<gildor> just as when you quit your program without closing a channel
<gildor> you also loose data
<mrvn> At a minimum I would like to give an error.
<gildor> the solution with "at_exit" could be better in this case
<gildor> but only implement it in a "debug" option
<mrvn> gildor: the "at_exit GC.full_major" or actually keeping a double linked list of active custom blocks?
<gildor> "double linked list of active blocks"
<gildor> (or a Weak.t)
<gildor> BTW, where is your code ?
<mrvn> That is also not foolproof. I can easily construct a case where it would free custom blocks that are still referenced and then use them.
<mrvn> Just my harddisk.
<gildor> The last piece of code i see you seem (on this irc channel), I see you are using register_global_root
<gildor> but in the wrong way
<gildor> i.e after having set it to a value
<gildor> you must register the place before setting its value
<mrvn> I do? So set it to 0, register and then to the real value?
<mrvn> line 105.
<mrvn> ahh, I see. 18.5.1 rule 4 explicitly says "before".
<gildor> indeed
<mrvn> What is the difference?
<gildor> The place is registered because when the Gc run, its address can be changed
<gildor> so if the place is registerd the Gc will change the address of the value according to where it has been moved
<mrvn> But that can only happen when some memory is allocated or not?
<gildor> indeed
<gildor> but you can never be sure
<gildor> better follow the manual
<mrvn> maybe one day ocaml will be really multithreaded and the GC runs in the background.
<gildor> maybe
<mrvn> Which is actually the reason I need libaio.
<gildor> I would also strongly recommend you to name your function "caml_aio.." rather than "aio_..."
<gildor> this can lead to calling the wrong function
<gildor> BTW, CAMLprim function should return "Val_unit"
<gildor> and not void
<gildor> (though it is not checked)
<gildor> I don't like the way you are using your register_global_root
<gildor> you must know that this is costly operation
<mrvn> I wondered about that but CAMLreturn0; complained about not being void.
<gildor> because you create a new root in the Gc which will be scanned every time
<mrvn> gildor: any suggestion how to avoid it?
<gildor> indeed, you must CAMLreturn(Val_unit), CAMLreturn0 is for C function
<gildor> and CAMLprim value at the beginning
<gildor> to avoid register_global_root you must work in 2 tier: keep caml value in caml code and have a lower datastructure in your custom block
_zack has joined #ocaml
<gildor> the lower data structure is limited to iocb + id required to make the link with your caml data structure
<mrvn> gildor: Ok. that was actually my plan.
<mrvn> hmm, or not.
<gildor> I have tried using register_global_root and my software was painfully slow
<mrvn> I was thinking about another custom block for the iocb.
<gildor> it should be limited to a few global variables
<mrvn> The best might actually be to allocate all iocbs when the context is created and put them in the custom block with the context.
ccpasteur has left #ocaml []
<mrvn> type t = { ctx : context; ios : (buffer * callback) array; cbios : cbio array }
<mrvn> Make that second array an array of such options.
<mrvn> hmm, now I get a segfault again.
<gildor> you should not store the iocb structure in the custom_block
<gildor> you should store a pointer to it
<mrvn> must even. can't have the GC moving it.
<gildor> because if the custom block get moved, the adress of the iocb datastructure will be changed
<gildor> I am under the impression that you stored the iocb in the custom_block, am I wrong ?
<mrvn> no. Currently iocbs aren't stored at all.
<gildor> BTW, after your fprintf(stderr, do a fflush(stderr), to be sure to have the message
<gildor> concerning your project, I you are willing to publish it, I would recommend using forge.ocamlcore.org
<mrvn> there are too many places with ocaml stuff.
<gildor> that the reason why we created a central forge for OCaml project only
Smerdyakov has joined #ocaml
<mrvn> I'm actualy working on revised fuse bindings that will work in combination with libaio so the code can service multiple requests concurrently while not being really multithreaded.
<mrvn> But I'm rather new to interfacing with C so this is a learning project.
<gildor> mrvn: you don't have started with the most simple subject
<gildor> aio require to create advanced data structure all around
<mrvn> true. but an interesting one.
<gildor> don't wait to have a good result fast, it will take time to debug it fully
<gildor> and host your OCaml projects on forge.ocamlcore.org ;-)
<mrvn> Once I have something that works.
<gildor> even before if you want to have people helping you
<gildor> (you can use CVS/SVN/git/darcs/hg there)
<mrvn> Well, I'm nearly there. The register_global_root() bit has to go I think and then it can be tested.
* gildor need to finish the household
dejj has joined #ocaml
ikaros has joined #ocaml
_zack has left #ocaml []
ikaros has quit [Client Quit]
Stefan_vK has joined #ocaml
<det> I use register_global_root in some code, does it really slow things down a lot ?
<gildor> depends on how much you use it
<gildor> it adds a root to scan in the Gc...
<gildor> so if you add many root in the Gc you slow it down a lot
vixey has joined #ocaml
<mrvn> Why is that? The cost for a new root should not be much bigger than for an object. I imagine a root being { root *prev, *next; value v; }
<mrvn> or similar.
Stefan_vK1 has quit [Read error: 110 (Connection timed out)]
<mrvn> gildor: What should the project name be? libaio-ocaml, caml-libaio, ocaml-linux-libaio?
<mrvn> So. I've eliminated the register_global_root calls and a simple test shows no errors. Time to merg this into the fuse bindings I have so far.
<det> mrvn, how do you get around register_global_root ?
alexyk has joined #ocaml
dejj has quit [Read error: 110 (Connection timed out)]
<mrvn> det: I allocate a block of size (max_ios + 1) for my context. Field 0 points to a custom block for the C context and the is either Val_unit or (unit -> unit) closures when the slot is in use.
<mrvn> The C context keeps track of the C iocbs and what slots are currently and use or free.
<det> and the is either...
<mrvn> and the rest is ...
<det> hmm
<mrvn> basically a type big_context = { ctx : context; (unit -> unit) option array; }
<mrvn> just hackish.
<det> what were you registering as a global root before ?
<mrvn> (unit -> unit) closures.
<det> the custom blocks ?
<mrvn> You have "let read ctx fd buf off fn = ..." and the (fn buffer) was registered globally.
<mrvn> When the read finishes then 'fn buffer ()' is called.
<det> I wonder why register_global_root would be so slow then
<det> I would expect it would be implemented in a similar way
<mrvn> Probably some implementation detailt that causes an overhead on every GC slice for every root.
<vixey> mrvn { root *prev, *next; value v; }?
<vixey> what is that *?
<mrvn> pointer. C syntax.
<vixey> oh ok
<det> C struct for a linked list?
<det> mrvn, hmm, I think your implementation can crash
<det> mrvn, because the closure can be moved by a collection
<mrvn> det: Then the GC will update the value in the big_context.
<mrvn> big_context is a (max_ios + 1) tupple, not a custom block.
<mrvn> The C part only stores the offset into the tuple in the iocbs and then gets the closure with Field(ml_ctx, slot)
<mrvn> Time to make dinner. *wave*
alexyk has quit []
alexyk has joined #ocaml
jeddhaberstro has joined #ocaml
<det> mrvn, but how does the C part get the address of the tuple?
alexyk has quit []
itewsh has joined #ocaml
alexyk has joined #ocaml
alexyk has quit [Client Quit]
alexyk has joined #ocaml
alexyk has quit [Client Quit]
_zack has joined #ocaml
sgnb has quit [kornbluth.freenode.net irc.freenode.net]
orbitz has quit [kornbluth.freenode.net irc.freenode.net]
gildor has quit [Killed by calvino.freenode.net (Nick collision)]
gildor has joined #ocaml
orbitz has joined #ocaml
sgnb has joined #ocaml
munga` has joined #ocaml
fremo_ has joined #ocaml
munga has quit [Read error: 110 (Connection timed out)]
fremo has quit [Read error: 110 (Connection timed out)]
svenl has quit [Read error: 110 (Connection timed out)]
smimou has quit [Read error: 110 (Connection timed out)]
fschwidom has quit [Read error: 104 (Connection reset by peer)]
fschwidom has joined #ocaml
itewsh has quit ["KTHXBYE"]
smimou has joined #ocaml
jeddhaberstro has quit []
fremo_ is now known as fremo
_zack has quit ["Leaving."]
bzzbzz has quit [Read error: 60 (Operation timed out)]
kirkordon has joined #ocaml
kirkordon has quit [Client Quit]
jlouis has quit [Remote closed the connection]
robocop has joined #ocaml
<robocop> Hello.
<robocop> I've you got an exemple of code, where, with module Str, I can search and replace a word by an other in a string ?
<robocop> I don't understand the documentation.
<robocop> what function use, etc...
<robocop> I think it's global_replace but i don't understand the history of \1; \2, etc...
robocop has quit ["Leaving."]
robocop has joined #ocaml
svenl has joined #ocaml
<thelema> robocop: still confused by \1, \2?
<robocop> yes.
<thelema> if you want to replace "foo" with "bar", you don't need \1, etc.
<thelema> if you want to replace "[foo]" with "(foo)", you'll need \1 to refer to the bit inside prefs
<thelema> s/prefs/parens/
<robocop> and \2 ?
<robocop> heu no
<robocop> sorry
<robocop> i've you got an exemple of code ?
<thelema> Str.global_replace (Str.regexp "ABC") "cba" "ABC ABC"
<thelema> should return "cba cba"
<thelema> Str.global_replace (Str.regexp "A(.)C") "c\1a" "ABC AZC"
<thelema> should return "cBa cZa"
<thelema> if you wanted to permute the characters in a string in a particular way, you could do:
<thelema> Str.global_replace (Str.regexp "(.)(.)(.)") "\3\1\2" "ABCAZC"
<thelema> and get "CABCAZ"
<gildor> mrvn: still there
<robocop> hum, okey, thanks a lot thelema.
<thelema> n/p
<robocop> Str.global_replace (Str.regexp "A(.)C") "c\1a" "ABC AZC";;
<robocop> Warning X: illegal backslash escape in string.
<robocop> - : string = "ABC AZC"
<gildor> Str.global_replace (Str.regexp "A(.)C") "c\\1a" "ABC AZC";;
<gildor> (\\ is required for legal ocaml string)
<gildor> (this will be interpreted as \1 in the regexp)
<robocop> but Str.global_replace (Str.regexp "A(.)C") "c\\1a" "ABC AZC";; return "ABC AZC".
<robocop> and not "cBa cZa".
<gildor> maybe try
<gildor> Str.global_replace (Str.regexp "A\\(.\\)C") "c\\1a" "ABC AZC";;
<robocop> okey, now, it's good :).
<robocop> Thanks a lot.
<gildor> np
<thelema> sorry, I fotgot the rediculous escaping needed for ocaml regexes
<thelema> *forgot
<vixey> yes lol
<vixey> doesn't any wizard write a camlp4 thingy?
<vixey> (for regex syntax)
<thelema> vixey: we just need an alternate quoting form for regex strings
<thelema> like perl's qq
<vixey> exactlya
<vixey> that's what I'm saying
<thelema> with quoting rules such that you don't need \\ = \
* thelema thinks maybe that'd require a different tokenizer
<thelema> which is quite a pain to do in p4
<flux> hmm, didn't micmatch (?) do something like that?
neoark has joined #ocaml
neoark is now known as Guest76367
Guest76367 has quit [Client Quit]
robocop has quit ["Leaving."]
robocop has joined #ocaml
seafood has joined #ocaml
hkBst has joined #ocaml
<robocop> Have you got any exemple to get anonymous arguments with Arg module, I don't understand the documentation too (:-°) ?
<robocop> actually, my code is : http://paste.pocoo.org/show/97069/
<thelema> robocop: what
<thelema> 's the problem?
<thelema> you seem to handle anonymous arguments by informing the user they shouldn't use them, and then ignoring.
<robocop> i want to parse argument like prog file -o output
<robocop> i found this code in a programme libre, freetennis.
<thelema> okay, so try [let anonFun s = filename := s]
<robocop> okey, it's goog. thanks.
<robocop> do you know what this code [exception File_cantopen;; let file = "fer";; let file = try (open_in file) with Sys_error "No such file or directory" -> raise File_cantopen;;] send me Exception: Sys_error "fer: No such file or directory". and not exception: File_cantopen
<robocop> ?
<flux> well, "fer: No such file or directory" is different from "No such file or directory"?
<thelema> try open_in file with Sys_error _ -> raise File_cantopen
<robocop> hum, ok, thanks.
<flux> Unix-module might give more exact error information
<robocop> what's the function to get all a file in a string ?
<robocop> there is "input_line file" but this function only get one line.
<robocop> like this :
<robocop> hum, no, like this : http://paste.pocoo.org/show/97080/
gene9 has joined #ocaml
itewsh has joined #ocaml
gene9 has quit ["Leaving"]
Anarchos has joined #ocaml
<Anarchos> for special purpose, i need to split the list of caml_local_roots in several lists. Anyway, i am no longer to compile ocamlc anymore since the pathname of the cmi files to generate are overwritten before calls to caml_sys_open. Is it something preventing to transform the call to caml_do_local_roots into several calls ?
mattam has joined #ocaml
robocop has quit [Read error: 104 (Connection reset by peer)]
robocop has joined #ocaml
<thelema> probably not, but why do you really need that many roots? The more roots you use, the worse performance the GC will have
<Anarchos> thelema i try to use a list of roots per thread, with a global lock around the interpreter. That because i use the CAMLparam macros before locking
robocop has left #ocaml []
<thelema> what do you gain by per-thread roots?
<Anarchos> i suspect that different threads using CAMLparam clobber the caml_local_roots global var
jlouis has joined #ocaml
itewsh has quit ["KTHXBYE"]
<Anarchos> thelema don't you think so ?
<thelema> My looking doesn't give me an answer one way or the other. Are you trying to make ocaml's GC work under multiple threads?
<Anarchos> yes, but i allow only one thread at a time to access the runtime loop (using global semaphore in caml_leave/enter_blocking_section)
fschwidom has quit [Remote closed the connection]
fschwidom has joined #ocaml
fschwidom has quit [Remote closed the connection]
<thelema> and you can't lock the roots to modify it?
<Anarchos> thelema no : i if you mix thread 1 local roots with thread 2 local roots in the list caml_local_roots, the calls to CAMLreturn will forget intermixed local C roots
slash_ has joined #ocaml
malc_ has joined #ocaml
Anarchos has quit [Read error: 145 (Connection timed out)]
jeddhaberstro has joined #ocaml
jonafan_ has joined #ocaml
slash_ has quit [Client Quit]
jonafan has quit [Read error: 110 (Connection timed out)]