caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Help interfacing with C
@ 2006-08-16 19:34 Nathaniel Gray
  2006-08-17  3:49 ` [Caml-list] " malc
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-16 19:34 UTC (permalink / raw)
  To: Caml List

Hi folks,

I'm having a heck of a time figuring out why this code *doesn't* work:

/* fdlist is a list of (file_descr * 'a) pairs.  Filter by FD_ISSET */
static value fdset_to_fdlist2(value fdlist, fd_set *fdset)
{
  value l, p, newres;
  value res = Val_int(0);

  Begin_roots4(l, p, res, newres);  /* I know, this is aggressive */
    for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
      p = Field(l, 0);
      int fd = Int_val(Field(p, 0));
      if (FD_ISSET(fd, fdset)) {
        newres = alloc_small(2, 0);
        Field(newres, 0) = p;
        Field(newres, 1) = res;
        res = newres;
      }
    }
  End_roots();
  return res;
}

But this code *does* work:

/* fdlist is a list of file_descr.  Filter by FD_ISSET */
static value fdset_to_fdlist(value fdlist, fd_set *fdset)
{
  value l;
  value res = Val_int(0);

  Begin_roots2(l, res);
    for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
      int fd = Int_val(Field(l, 0));
      if (FD_ISSET(fd, fdset)) {
        value newres = alloc_small(2, 0);
        Field(newres, 0) = Val_int(fd);
        Field(newres, 1) = res;
        res = newres;
      }
    }
  End_roots();
  return res;
}

The second sample comes directly from otherlibs/unix/select.c in the
ocaml compiler, and the first is part of a modification I'm writing to
have select work on (file_descr * 'a) pairs instead of plain file
descriptors.  The Begin_roots4 line was originally Begin_roots3(l,
res, newres), but it doesn't seem to make any difference.  When I run
in gdb the failure looks like this:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
0x000051ac in caml_array_unsafe_get (array=1, index=1) at array.c:101
101       if (Tag_val(array) == Double_array_tag)
(gdb) bt
#0  0x000051ac in caml_array_unsafe_get (array=1, index=1) at array.c:101
#1  0x0002dd84 in caml_interprete (prog=0x205000, prog_size=949932) at
interp.c:869
#2  0x00021bd8 in caml_main (argv=0xbfffe934) at startup.c:414
#3  0x00002630 in main (argc=2, argv=0xbfffe934) at main.c:35

It fails on line 869 of this code in caml_interprete:
867         Instruct(C_CALL2):
868           Setup_for_c_call;
869           accu = Primitive(*pc)(accu, sp[1]);
870           Restore_after_c_call;

I've tried poking in gdb, but as far as I can tell the result of the
function is a well-formed list.  Any suggestions?

Thanks!
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Help interfacing with C
  2006-08-16 19:34 Help interfacing with C Nathaniel Gray
@ 2006-08-17  3:49 ` malc
  2006-08-18 21:00   ` Nathaniel Gray
  2006-08-17  5:56 ` Bardur Arantsson
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 18+ messages in thread
From: malc @ 2006-08-17  3:49 UTC (permalink / raw)
  To: Nathaniel Gray; +Cc: Caml List

On Wed, 16 Aug 2006, Nathaniel Gray wrote:

> Hi folks,
>
> I'm having a heck of a time figuring out why this code *doesn't* work:
>
> /* fdlist is a list of (file_descr * 'a) pairs.  Filter by FD_ISSET */
> static value fdset_to_fdlist2(value fdlist, fd_set *fdset)
> {
> value l, p, newres;
> value res = Val_int(0);
>
> Begin_roots4(l, p, res, newres);  /* I know, this is aggressive */
>   for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
>     p = Field(l, 0);
>     int fd = Int_val(Field(p, 0));

This here (expanded) does Int_val (Field (Field (l, 0), 0))

<snip>

>     int fd = Int_val(Field(l, 0));

<snip>

I think the difference is self-evident.

--
mailto:malc@pulsesoft.com


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help interfacing with C
  2006-08-16 19:34 Help interfacing with C Nathaniel Gray
  2006-08-17  3:49 ` [Caml-list] " malc
@ 2006-08-17  5:56 ` Bardur Arantsson
  2006-08-18  7:10   ` [Caml-list] " Olivier Andrieu
  2006-08-18 21:33   ` [Caml-list] " Nathaniel Gray
  2006-08-18  8:46 ` [Caml-list] " Damien Doligez
  2006-08-23 23:36 ` Nathaniel Gray
  3 siblings, 2 replies; 18+ messages in thread
From: Bardur Arantsson @ 2006-08-17  5:56 UTC (permalink / raw)
  To: caml-list

Nathaniel Gray wrote:
> Hi folks,
[--snip--]
> have select work on (file_descr * 'a) pairs instead of plain file
> descriptors.

It's much easier than that; just define a conversion in OCaml:

    external file_descr_to_int : file_descr -> int = "%identity";
    external int_to_file_descr : int -> file_descr = "%identity";

and use

    let my_select r w e t =
       let r' = List.map file_descr_to_int r
       and w' = List.map file_descr_to_int w
       and e' = List.map file_descr_to_int e
       in
         Unix.select r' w' e' t;;

You seem to be doing the mapping of the result values, but that is just 
a question of mapping int_to_file_descr over the result lists.

Of course this may be rather slower than your version, but Unix.select 
is very very slow anyway since it's allocating at least one list for 
every single call... and iterating through all(?) the file descriptors 
in the input FD_SETs as well.

[Shameless plug below: If you want better performance, you might want
to try

 
http://www.imada.sdu.dk/~bardur/personal/45-programs/ocaml-events/ocaml-events-0.1.0.tar.bz2

I must warn you, though, that there are no timers or signal handling: It 
turned out I didn't them for my particular application, so I haven't 
bothered adding support. The actual FD polling/selection has worked very 
reliably for me.]

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

The truth is out there, but lies are in your head.
                                      Terry Pratchett, 'Hogfather'


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-17  5:56 ` Bardur Arantsson
@ 2006-08-18  7:10   ` Olivier Andrieu
  2006-08-18 15:50     ` Bardur Arantsson
  2006-08-18 21:33   ` [Caml-list] " Nathaniel Gray
  1 sibling, 1 reply; 18+ messages in thread
From: Olivier Andrieu @ 2006-08-18  7:10 UTC (permalink / raw)
  To: Bardur Arantsson; +Cc: caml-list

 Bardur Arantsson [Thursday 17 August 2006] :
 >
 > Nathaniel Gray wrote:
 > > Hi folks,
 > [--snip--]
 > > have select work on (file_descr * 'a) pairs instead of plain file
 > > descriptors.
 > 
 > It's much easier than that; just define a conversion in OCaml:
 > 
 >     external file_descr_to_int : file_descr -> int = "%identity";
 >     external int_to_file_descr : int -> file_descr = "%identity";

That will only work on Unix: on Windows, a file_descr is not an int
but a custom block.

file_descr work fine as keys for a Hashtbl though.

-- 
   Olivier


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Help interfacing with C
  2006-08-16 19:34 Help interfacing with C Nathaniel Gray
  2006-08-17  3:49 ` [Caml-list] " malc
  2006-08-17  5:56 ` Bardur Arantsson
@ 2006-08-18  8:46 ` Damien Doligez
  2006-08-18 20:09   ` Nathaniel Gray
  2006-08-23 23:36 ` Nathaniel Gray
  3 siblings, 1 reply; 18+ messages in thread
From: Damien Doligez @ 2006-08-18  8:46 UTC (permalink / raw)
  To: Caml List

Hello,

On 2006-08-16, at 21:34, Nathaniel Gray wrote:

> I'm having a heck of a time figuring out why this code *doesn't* work:

Unless you really know what you're doing, you should use the new macros
(CAMLparam*, CAMLlocal*, CAMLreturn) instead of Begin_roots/End_roots.
They are slightly less error-prone.

> /* fdlist is a list of (file_descr * 'a) pairs.  Filter by FD_ISSET */
> static value fdset_to_fdlist2(value fdlist, fd_set *fdset)
> {
>  value l, p, newres;
>  value res = Val_int(0);
>
>  Begin_roots4(l, p, res, newres);  /* I know, this is aggressive */
>    for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
>      p = Field(l, 0);
>      int fd = Int_val(Field(p, 0));
>      if (FD_ISSET(fd, fdset)) {
>        newres = alloc_small(2, 0);
>        Field(newres, 0) = p;
>        Field(newres, 1) = res;
>        res = newres;
>      }
>    }
>  End_roots();
>  return res;
> }

Look at your Begin_roots4.  One of the four parameters is
uninitialized when you first call alloc_small.  If the minor GC
is triggered by this allocation, it can result in a segment
violation or worse.

-- Damien

PS. Maybe there are some other bugs in your code.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help interfacing with C
  2006-08-18  7:10   ` [Caml-list] " Olivier Andrieu
@ 2006-08-18 15:50     ` Bardur Arantsson
  0 siblings, 0 replies; 18+ messages in thread
From: Bardur Arantsson @ 2006-08-18 15:50 UTC (permalink / raw)
  To: caml-list

Olivier Andrieu wrote:
>  Bardur Arantsson [Thursday 17 August 2006] :
>  >
>  > Nathaniel Gray wrote:
>  > > Hi folks,
>  > [--snip--]
>  > > have select work on (file_descr * 'a) pairs instead of plain file
>  > > descriptors.
>  > 
>  > It's much easier than that; just define a conversion in OCaml:
>  > 
>  >     external file_descr_to_int : file_descr -> int = "%identity";
>  >     external int_to_file_descr : int -> file_descr = "%identity";
> 
> That will only work on Unix: on Windows, a file_descr is not an int
> but a custom block.
> 
> file_descr work fine as keys for a Hashtbl though.
> 

Well, AFAICT he's accessing/creating them through Int_val/Val_int, so I 
kind of assumed...

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

- Evil will always triumph over Good, because Good is dumb.
                                          Dark Helmet / Spaceballs


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Help interfacing with C
  2006-08-18  8:46 ` [Caml-list] " Damien Doligez
@ 2006-08-18 20:09   ` Nathaniel Gray
  0 siblings, 0 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-18 20:09 UTC (permalink / raw)
  To: Damien Doligez; +Cc: Caml List

On 8/18/06, Damien Doligez <damien.doligez@inria.fr> wrote:
> Hello,
>
> On 2006-08-16, at 21:34, Nathaniel Gray wrote:
>
> > I'm having a heck of a time figuring out why this code *doesn't* work:
>
> Unless you really know what you're doing, you should use the new macros
> (CAMLparam*, CAMLlocal*, CAMLreturn) instead of Begin_roots/End_roots.
> They are slightly less error-prone.

This is a patch to unix.c in the compiler so I'm following the idiom used there.

> > /* fdlist is a list of (file_descr * 'a) pairs.  Filter by FD_ISSET */
> > static value fdset_to_fdlist2(value fdlist, fd_set *fdset)
> > {
> >  value l, p, newres;
> >  value res = Val_int(0);
> >
> >  Begin_roots4(l, p, res, newres);  /* I know, this is aggressive */
> >    for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
> >      p = Field(l, 0);
> >      int fd = Int_val(Field(p, 0));
> >      if (FD_ISSET(fd, fdset)) {
> >        newres = alloc_small(2, 0);
> >        Field(newres, 0) = p;
> >        Field(newres, 1) = res;
> >        res = newres;
> >      }
> >    }
> >  End_roots();
> >  return res;
> > }
>
> Look at your Begin_roots4.  One of the four parameters is
> uninitialized when you first call alloc_small.  If the minor GC
> is triggered by this allocation, it can result in a segment
> violation or worse.

That's not the problem, but thanks for the tip.  The code crashes
after alloc_small, and quite reliably.

> PS. Maybe there are some other bugs in your code.

You're being too kind.  ;^)  There certainly is at least one other
bug, and I still don't know what it is.  Any other ideas?

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Help interfacing with C
  2006-08-17  3:49 ` [Caml-list] " malc
@ 2006-08-18 21:00   ` Nathaniel Gray
  0 siblings, 0 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-18 21:00 UTC (permalink / raw)
  To: malc; +Cc: Caml List

On 8/16/06, malc <malc@pulsesoft.com> wrote:
> On Wed, 16 Aug 2006, Nathaniel Gray wrote:
>
> > Hi folks,
> >
> > I'm having a heck of a time figuring out why this code *doesn't* work:
> >
> > /* fdlist is a list of (file_descr * 'a) pairs.  Filter by FD_ISSET */
> > static value fdset_to_fdlist2(value fdlist, fd_set *fdset)
> > {
> > value l, p, newres;
> > value res = Val_int(0);
> >
> > Begin_roots4(l, p, res, newres);  /* I know, this is aggressive */
> >   for (l = fdlist; l != Val_int(0); l = Field(l, 1)) {
> >     p = Field(l, 0);
> >     int fd = Int_val(Field(p, 0));
>
> This here (expanded) does Int_val (Field (Field (l, 0), 0))
>
> <snip>
>
> >     int fd = Int_val(Field(l, 0));
>
> <snip>
>
> I think the difference is self-evident.

Indeed, it's the entire point of the exercise.  In the first version l
is a list of (fd, 'a) pairs, in the second it's a list of fds.

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-17  5:56 ` Bardur Arantsson
  2006-08-18  7:10   ` [Caml-list] " Olivier Andrieu
@ 2006-08-18 21:33   ` Nathaniel Gray
  2006-08-18 22:24     ` Bardur Arantsson
  2006-08-19  9:03     ` Richard Jones
  1 sibling, 2 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-18 21:33 UTC (permalink / raw)
  To: Bardur Arantsson; +Cc: caml-list

On 8/16/06, Bardur Arantsson <spam@scientician.net> wrote:
> Nathaniel Gray wrote:
> > Hi folks,
> [--snip--]
> > have select work on (file_descr * 'a) pairs instead of plain file
> > descriptors.
>
> It's much easier than that; just define a conversion in OCaml:
>
>     external file_descr_to_int : file_descr -> int = "%identity";
>     external int_to_file_descr : int -> file_descr = "%identity";
>
> and use
>
>     let my_select r w e t =
>        let r' = List.map file_descr_to_int r
>        and w' = List.map file_descr_to_int w
>        and e' = List.map file_descr_to_int e
>        in
>          Unix.select r' w' e' t;;
>
> You seem to be doing the mapping of the result values, but that is just
> a question of mapping int_to_file_descr over the result lists.

Thanks, but this doesn't really help.  Perhaps I should say what I'm
trying to accomplish instead of trying to let the types speak for me.
The point is that when you select on a list of file descriptors
there's a very good chance that you don't *only* care that file
descriptor f is ready, you also have some ocaml data structure
associated with f that you want to use with it in some way.  For
example, you probably have a string to write or a buffer to read into.

The current API is sort of a minimal translation of the select system
call to OCaml, which is a good starting point, but not great IMHO.  In
order to match up each file descriptor to its data you have to scan
the output fd list yet again, after it's already been done once at the
C level, and since you don't know how/if it's sorted you end up with
unsatisfying time complexity for the whole thing.  It's not critical,
since the lists are small, but it hardly brings a smile to your face.

On the other hand, imagine a select2 that takes lists of (fd, 'a)
pairs and returns the same.  The results become incredibly easy to
handle, with no scanning necessary.  You probably just List.iter a
simple read/write function over the result and you're done.

>
> Of course this may be rather slower than your version, but Unix.select
> is very very slow anyway since it's allocating at least one list for
> every single call... and iterating through all(?) the file descriptors
> in the input FD_SETs as well.
>
> [Shameless plug below: If you want better performance, you might want
> to try
>
>
> http://www.imada.sdu.dk/~bardur/personal/45-programs/ocaml-events/ocaml-events-0.1.0.tar.bz2
>
> I must warn you, though, that there are no timers or signal handling: It
> turned out I didn't them for my particular application, so I haven't
> bothered adding support. The actual FD polling/selection has worked very
> reliably for me.]



-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help interfacing with C
  2006-08-18 21:33   ` [Caml-list] " Nathaniel Gray
@ 2006-08-18 22:24     ` Bardur Arantsson
  2006-08-19  0:33       ` [Caml-list] " Nathaniel Gray
  2006-08-19  9:03     ` Richard Jones
  1 sibling, 1 reply; 18+ messages in thread
From: Bardur Arantsson @ 2006-08-18 22:24 UTC (permalink / raw)
  To: caml-list

Nathaniel Gray wrote:
> On 8/16/06, Bardur Arantsson <spam@scientician.net> wrote:
>> Nathaniel Gray wrote:
>> > Hi folks,
>> [--snip--]
> 
> Thanks, but this doesn't really help.  Perhaps I should say what I'm
> trying to accomplish instead of trying to let the types speak for me.
> The point is that when you select on a list of file descriptors
> there's a very good chance that you don't *only* care that file
> descriptor f is ready, you also have some ocaml data structure
> associated with f that you want to use with it in some way.  For
> example, you probably have a string to write or a buffer to read into.
> 
> The current API is sort of a minimal translation of the select system
> call to OCaml, which is a good starting point, but not great IMHO.  In
> order to match up each file descriptor to its data you have to scan
> the output fd list yet again, after it's already been done once at the
> C level, and since you don't know how/if it's sorted you end up with
> unsatisfying time complexity for the whole thing.  It's not critical,
> since the lists are small, but it hardly brings a smile to your face.
> 
> On the other hand, imagine a select2 that takes lists of (fd, 'a)
> pairs and returns the same.  The results become incredibly easy to
> handle, with no scanning necessary.  You probably just List.iter a
> simple read/write function over the result and you're done.
> 

Have you tried to benchmark the naive implementation(*) versus a "bare" 
Unix.select? I shouldn't think you a little bit extra of scanning the 
list which is O(n) in the number of _active_ file descriptors matters 
with all the O(MAX_FD) stuff that's going on in select(). I would expect 
most of the time to be spent doing the actual system call.

(*) That is, an implementation which puts (fd, associated value) in a 
hashtable indexed by the file_descr and does the scanning after doing 
the Unix.select.

Cheers,

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

- This is supposed to be a happy occasion. Let's not *bicker* and
*argue* about who killed who.
                                 'Monty Python and the Holy Grail'


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-18 22:24     ` Bardur Arantsson
@ 2006-08-19  0:33       ` Nathaniel Gray
  2006-08-19  6:03         ` Bardur Arantsson
  2006-08-19  8:30         ` Olivier Andrieu
  0 siblings, 2 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-19  0:33 UTC (permalink / raw)
  To: Bardur Arantsson; +Cc: caml-list

On 8/18/06, Bardur Arantsson <spam@scientician.net> wrote:
> Nathaniel Gray wrote:
> > On 8/16/06, Bardur Arantsson <spam@scientician.net> wrote:
> >> Nathaniel Gray wrote:
> >> > Hi folks,
> >> [--snip--]
> >
> > Thanks, but this doesn't really help.  Perhaps I should say what I'm
> > trying to accomplish instead of trying to let the types speak for me.
> > The point is that when you select on a list of file descriptors
> > there's a very good chance that you don't *only* care that file
> > descriptor f is ready, you also have some ocaml data structure
> > associated with f that you want to use with it in some way.  For
> > example, you probably have a string to write or a buffer to read into.
> >
> > The current API is sort of a minimal translation of the select system
> > call to OCaml, which is a good starting point, but not great IMHO.  In
> > order to match up each file descriptor to its data you have to scan
> > the output fd list yet again, after it's already been done once at the
> > C level, and since you don't know how/if it's sorted you end up with
> > unsatisfying time complexity for the whole thing.  It's not critical,
> > since the lists are small, but it hardly brings a smile to your face.
> >
> > On the other hand, imagine a select2 that takes lists of (fd, 'a)
> > pairs and returns the same.  The results become incredibly easy to
> > handle, with no scanning necessary.  You probably just List.iter a
> > simple read/write function over the result and you're done.
> >
>
> Have you tried to benchmark the naive implementation(*) versus a "bare"
> Unix.select? I shouldn't think you a little bit extra of scanning the
> list which is O(n) in the number of _active_ file descriptors matters
> with all the O(MAX_FD) stuff that's going on in select(). I would expect
> most of the time to be spent doing the actual system call.
>
> (*) That is, an implementation which puts (fd, associated value) in a
> hashtable indexed by the file_descr and does the scanning after doing
> the Unix.select.

Let me be clear about this -- it's not really about performance.  I'm
looking at the entire sequence of operations and data structures
needed to make a select call.  Here's a typical example with the
current API:

(* You have a data structure with some file descriptors and auxilliary data *)
let foo = [(fd1, "hello"); (fd2, "world"); (fd3, "baz")] in
(* Now you need a list of file descriptors *)
let fds = List.map fst foo in
(* Feed them to select *)
let _, outs, _ = Unix.select [] fds [] (-1.0) in
(* Now do something with each active descriptor *)
List.iter (fun fd ->
   let data = List.assoc fd foo in
   do_something data) outs

Here's how it would work with my proposed select2:

(* You have a data structure with some file descriptors and auxilliary data *)
let foo = [(fd1, "hello"); (fd2, "world"); (fd3, "baz")] in
(* Feed it to select2 *)
let _, outs, _ = Unix.select2 [] foo [] (-1.0) in
(* Now do something with the data *)
List.iter (fun (fd, data) -> do_something data) outs

The whole thing is much nicer.  You don't need a separate list of file
descriptors that exists only to be fed to select.  You don't need to
do any work afterwards to find the data associated with a file
descriptor.  The fact that it's also faster (assuming it truly *is*
faster) is just the icing on the cake.  Now I'll grant that I've
chosen a convenient data representation for my purposes, but it's not
like I've cheated badly -- a list of (fd, data) or (fd, closure) pairs
would be a sensible thing to use in this kind of code.

Now of course this could all be done at the ocaml level, but wouldn't
it be nicer to do the elegant thing in the first place instead of
cleaning up the mess afterwards?  ;^)

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help interfacing with C
  2006-08-19  0:33       ` [Caml-list] " Nathaniel Gray
@ 2006-08-19  6:03         ` Bardur Arantsson
  2006-08-21 22:45           ` [Caml-list] " Nathaniel Gray
  2006-08-19  8:30         ` Olivier Andrieu
  1 sibling, 1 reply; 18+ messages in thread
From: Bardur Arantsson @ 2006-08-19  6:03 UTC (permalink / raw)
  To: caml-list

Nathaniel Gray wrote:
> On 8/18/06, Bardur Arantsson <spam@scientician.net> wrote:
>> Nathaniel Gray wrote:
>> > On 8/16/06, Bardur Arantsson <spam@scientician.net> wrote:
>> >> Nathaniel Gray wrote:
>> >> > Hi folks,
>> >> [--snip--]
> Let me be clear about this -- it's not really about performance.  I'm
> looking at the entire sequence of operations and data structures
> needed to make a select call.  Here's a typical example with the
> current API:
[--snip-- example --snip--]

Ok, I did understand _what_ you are trying to do, I'm just not sure why 
anyone wouldn't choose the path of least resistance -- a solution in C 
is likely to be more error-prone (as you've discovered ;)) and harder to 
maintain if there are changes in OCaml internals -- whereas Unix.select 
is likely to remain that way "forever". Of course if the aim of the 
whole exercise is to get the modified select included in OCaml then I 
guess there's your motivation for doing it in C ;).

However, if you just want a nicer interface then there are other 
solutions such as Gerd Stolpmann's "Equeue" framework. I would just use 
that instead of worrying about Unix.select. It provides much nicer 
abstractions:

    http://www.ocaml-programming.de/packages/documentation/equeue/

Cheers,

-- 
Bardur Arantsson
<bardurREMOVE@THISscientician.net>

- If you can remember drinking it, you obviously didn't drink
enough of it.
                                                                Me


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-19  0:33       ` [Caml-list] " Nathaniel Gray
  2006-08-19  6:03         ` Bardur Arantsson
@ 2006-08-19  8:30         ` Olivier Andrieu
  2006-08-21 22:35           ` Nathaniel Gray
  1 sibling, 1 reply; 18+ messages in thread
From: Olivier Andrieu @ 2006-08-19  8:30 UTC (permalink / raw)
  To: Nathaniel Gray; +Cc: caml-list

 Nathaniel Gray [Friday 18 August 2006] :
 > Now of course this could all be done at the ocaml level, but
 > wouldn't it be nicer to do the elegant thing in the first place
 > instead of cleaning up the mess afterwards?  ;^)

Erm, doing things on the C side isn't especially "elegant",
sorry. It's way more error-prone, more complicated to compile/link
against, and in your case it's not even portable (your version is
Unix-only).

Just write your select2 using an intermediate Hashtbl: it probably
won't be much slower (unless you have hundreds of fd maybe). 

-- 
   Olivier


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-18 21:33   ` [Caml-list] " Nathaniel Gray
  2006-08-18 22:24     ` Bardur Arantsson
@ 2006-08-19  9:03     ` Richard Jones
  2006-08-19  9:41       ` skaller
  1 sibling, 1 reply; 18+ messages in thread
From: Richard Jones @ 2006-08-19  9:03 UTC (permalink / raw)
  To: Nathaniel Gray; +Cc: Bardur Arantsson, caml-list

On Fri, Aug 18, 2006 at 02:33:23PM -0700, Nathaniel Gray wrote:
> Thanks, but this doesn't really help.  Perhaps I should say what I'm
> trying to accomplish instead of trying to let the types speak for me.
> The point is that when you select on a list of file descriptors
> there's a very good chance that you don't *only* care that file
> descriptor f is ready, you also have some ocaml data structure
> associated with f that you want to use with it in some way.  For
> example, you probably have a string to write or a buffer to read into.

It sounds also like you shouldn't use select at all, but consider some
of the more modern alternatives.  Here is a good place to start:

http://www.kegel.com/c10k.html#nb.select

Rich.

-- 
Richard Jones, CTO Merjis Ltd.
Merjis - web marketing and technology - http://merjis.com
Team Notepad - intranets and extranets for business - http://team-notepad.com


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-19  9:03     ` Richard Jones
@ 2006-08-19  9:41       ` skaller
  0 siblings, 0 replies; 18+ messages in thread
From: skaller @ 2006-08-19  9:41 UTC (permalink / raw)
  To: Richard Jones; +Cc: Nathaniel Gray, Bardur Arantsson, caml-list

On Sat, 2006-08-19 at 10:03 +0100, Richard Jones wrote:

> It sounds also like you shouldn't use select at all, but consider some
> of the more modern alternatives.  Here is a good place to start:
> 
> http://www.kegel.com/c10k.html#nb.select

Yeah but if you were doing that you'd probably want 
to use the demux library which is part of Felix ..
in which case you'd want to use it as part of the
context switching too .. in which case you might was
well just use Felix instead of Ocaml :)

I'd be thinking of Equeue if you do want to use 'modern'
alternatives, since it has generic support for 
different notification methods: looks like you could
use a select binding, and switch to some other method
later if you weren't happy with the performance.
Perhaps Gerd can confirm this?

Felix chooses the best of: epoll, kqueue, poll,
windows IOcompletion ports, Solaris iocompletion ports,
and select and abstracts the lot away. The end user
just does blocking I/O .. but it only blocks fibres,
not threads (unless there is nothing ready of course).
[Doesn't the VMthreads of bytecode do this too?]

The difficulty getting this right should not be underestimated.
For example, epoll is available in Linux 2.4 but it doesn't work:
the config script actually has to call it to find out it is
dysfunctional. Felix outperforms C10K by at least 2 decimal
orders of magnitude, without resorting to callbacks, and
without assembler hacks like stack swapping. It does this by
*translating* code using a thread model into code using a
callback model. The demux library demultiplexes notifications
and hooks the results into the scheduling algorithm.

I believe both Haskell and MLton can do this kind of thing
too (though I'm not sure): continuation passing is essential.
I don't think Ocaml uses continuation passing, however most
bytecode interpreters do (including for example Python)
because it's the only way to write a bytecode interpreter :)
Felix uses heaped continuations for procedures, but the
stack for functions.. a fairly novel and rather ugly mix
(required for C compatibility .. and also yielding the best
performance).

All these systems, either implicitly or, now in the case
of Felix quite explicitly .. are replacing poor operating
system designs like Unix. You have to remember Unix was
designed for batch processes with some time sharing:
its hardly surprising it doesn't work well with threads
and real time events .. it was designed to isolate the
end user from these features!

-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-19  8:30         ` Olivier Andrieu
@ 2006-08-21 22:35           ` Nathaniel Gray
  0 siblings, 0 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-21 22:35 UTC (permalink / raw)
  To: Olivier Andrieu; +Cc: caml-list

On 8/19/06, Olivier Andrieu <oandrieu@nerim.net> wrote:
>  Nathaniel Gray [Friday 18 August 2006] :
>  > Now of course this could all be done at the ocaml level, but
>  > wouldn't it be nicer to do the elegant thing in the first place
>  > instead of cleaning up the mess afterwards?  ;^)
>
> Erm, doing things on the C side isn't especially "elegant",
> sorry. It's way more error-prone, more complicated to compile/link
> against, and in your case it's not even portable (your version is
> Unix-only).

I see.  In that case I move we eliminate the whole Unix module.  It's
all written in error-prone, complicated, non-portable C!

The point is that we need *some* interface to the select system call.
By it's nature, it must be written in C.  We can, with very little
work (about 10-20 LOC or less), have a more elegant interface to the
select system call that reduces the amount of cruft needed to make a
typical select call.  I'm doing this work, because it's useful to me.
Because I believe it could be useful to others, I'm also trying to
create a patch against the compiler for submission to the ocaml team.
I'm not claiming it's a revolutionary change or massively faster, just
an interface that's more pleasant to program with.

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Caml-list] Re: Help interfacing with C
  2006-08-19  6:03         ` Bardur Arantsson
@ 2006-08-21 22:45           ` Nathaniel Gray
  0 siblings, 0 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-21 22:45 UTC (permalink / raw)
  To: Bardur Arantsson; +Cc: caml-list

On 8/18/06, Bardur Arantsson <spam@scientician.net> wrote:
>
> Of course if the aim of the
> whole exercise is to get the modified select included in OCaml then I
> guess there's your motivation for doing it in C ;).

Ding ding ding!  Give that man a cigar!  ;^)

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Help interfacing with C
  2006-08-16 19:34 Help interfacing with C Nathaniel Gray
                   ` (2 preceding siblings ...)
  2006-08-18  8:46 ` [Caml-list] " Damien Doligez
@ 2006-08-23 23:36 ` Nathaniel Gray
  3 siblings, 0 replies; 18+ messages in thread
From: Nathaniel Gray @ 2006-08-23 23:36 UTC (permalink / raw)
  To: Caml List

On 8/16/06, Nathaniel Gray <n8gray@gmail.com> wrote:
> Hi folks,
>
> I'm having a heck of a time figuring out why this code *doesn't* work:

I just wanted to mention that the reason my code was failing had
nothing to do with C.  I accidentally had wrapped the function with an
incorrect type.  Big thanks to malc for actually trying the code out
and convincing me to look elsewhere.

Cheers,
-n8

-- 
>>>-- Nathaniel Gray -- Caltech Computer Science ------>
>>>-- Mojave Project -- http://mojave.cs.caltech.edu -->


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2006-08-24 14:48 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-08-16 19:34 Help interfacing with C Nathaniel Gray
2006-08-17  3:49 ` [Caml-list] " malc
2006-08-18 21:00   ` Nathaniel Gray
2006-08-17  5:56 ` Bardur Arantsson
2006-08-18  7:10   ` [Caml-list] " Olivier Andrieu
2006-08-18 15:50     ` Bardur Arantsson
2006-08-18 21:33   ` [Caml-list] " Nathaniel Gray
2006-08-18 22:24     ` Bardur Arantsson
2006-08-19  0:33       ` [Caml-list] " Nathaniel Gray
2006-08-19  6:03         ` Bardur Arantsson
2006-08-21 22:45           ` [Caml-list] " Nathaniel Gray
2006-08-19  8:30         ` Olivier Andrieu
2006-08-21 22:35           ` Nathaniel Gray
2006-08-19  9:03     ` Richard Jones
2006-08-19  9:41       ` skaller
2006-08-18  8:46 ` [Caml-list] " Damien Doligez
2006-08-18 20:09   ` Nathaniel Gray
2006-08-23 23:36 ` Nathaniel Gray

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).