Browse thread
[ANN] coThreads 0.10
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | skaller <skaller@u...> |
| Subject: | Re: [Caml-list] [ANN] coThreads 0.10 |
On Tue, 2007-09-18 at 16:23 +1000, Erik de Castro Lopo wrote:
> skaller wrote:
> > It is not clear that a seek to an invalid position in the file
> > is going to succeed. It's also not clear to me that the seek
> > argument isn't 32 bits (depends on complex ugly GNU macro
> > hackery what type off_t is .. my Caml got built with
> > the LARGE_FILE macro thing so it should be 64 bits).
>
> Shouldn't off_t always be 64 bits on a 64 bit CPU?
I don't know. I traced through the code and did some debugging,
and the problem is that system wide mutex is emulated by using
locking on an lseek on a (deleted) lock file. The seek address
is a magic number which is rather large, and this appears to
cause the EINVAL errno on the lseek call.
let lock_fd =
print_endline "CREATING MUTEX";
let lock_name = fresh_name "_mutex" in
remove_exists lock_name;
let fd = openfile lock_name [O_WRONLY; O_CREAT] file_perm in
remove_exists lock_name;
fd
type t = int (* The offset *)
let create = fresh_number
let rec lock lk =
print_endline ("LOCK " ^ string_of_int lk);
if lk <> lseek lock_fd lk SEEK_SET then assert false;
lockf lock_fd F_LOCK 1
So basically a mutex is modelled by an offset,
which is created by fresh_number routine, and using
Unix discretionary locks with lockf function, which
is based on the current position in the file.
Well, I don't see how the lseek can fail unless there
is a filesize constraint somewhere detecting that
1695112678495748100
is an invalid offset for lseek.
A possible patch is to take this in process.coordinator
(* fresh_number fresh_name ensure that there won't exist number/name
confliction between running processes.
*)
let fresh_number =
let usable_size = Sys.word_size -2 in
let bits_of_id = 16 in (* Should be sufficient in most OS *)
let bits_of_num = usable_size - bits_of_id in
let counter = ref 0 in
fun () ->
let self_id = id (self ()) in
let id_part = bit_chop_to_n bits_of_id self_id in
let num_part =
counter := bit_chop_to_n bits_of_num (!counter + 1);
!counter in
(id_part lsl bits_of_num) + num_part
and use the line 2:
let usable_size = 30 in
instead (though I didn't try it, some other places may need
to replace Sys.word_size the same way for it to work
properly).
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net