caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Using C threads
@ 2011-02-28 21:56 Niki Yoshiuchi
  2011-03-01 12:14 ` Dmitry Bely
  0 siblings, 1 reply; 9+ messages in thread
From: Niki Yoshiuchi @ 2011-02-28 21:56 UTC (permalink / raw)
  To: caml-list

I'm trying to call some OCaml code from a thread created in C.  I know
I'm supposed to call caml_c_thread_{un}register, however this pretty
much guarantees a segfault.  If I leave them out, my code works fine
so long as I don't try and do much of anything.  Here's my code
stripped down to the bare minimum:

C code:

void *my_thread(void *ptr)
{
    caml_c_thread_register();
    for(;;)
    {
        caml_acquire_runtime_system();
        caml_callback(*caml_named_value("my_callback"), Val_unit);
        caml_release_runtime_system();
    }
    caml_c_thread_unregister(); // I realize this will never be
called.  I've tried without the for loop as well, same result
}

CAMLprim value caml_create_callback(value unit)
{
    pthread_t thread1;
    pthread_create(&thread1, NULL, my_thread, NULL);
    return Val_unit;
}

OCaml code:

external create_callback : unit -> unit = "caml_create_callback"

let my_thread () =
    ()

let _ =
    Callback.register "my_callback" random_thread;
    create_callback ();
    while true do
        ()
    done

This code will segfault immediately.  If I remove the thread_register
functions it will run as expected.  If I try and do anything more than
just return unit, it will segfault unless I add in some sleep
statements.  I'm assuming that the sleep function acts as a sort of
poor-man's thread synchronizer.  I've tried endless permutations

Other important info - I'm using OCaml 3.12 and gcc 4.3.2 on Linux.
The return value of caml_c_thread_register is 1, which means that it
is successfully returning.

Thanks,
-Niki Yoshiuchi

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

* Re: [Caml-list] Using C threads
  2011-02-28 21:56 [Caml-list] Using C threads Niki Yoshiuchi
@ 2011-03-01 12:14 ` Dmitry Bely
  2011-03-03 22:16   ` Niki Yoshiuchi
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Bely @ 2011-03-01 12:14 UTC (permalink / raw)
  To: caml-list

On Tue, Mar 1, 2011 at 12:56 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
> I'm trying to call some OCaml code from a thread created in C.  I know
> I'm supposed to call caml_c_thread_{un}register, however this pretty
> much guarantees a segfault.  If I leave them out, my code works fine
> so long as I don't try and do much of anything.  Here's my code
> stripped down to the bare minimum:
>
> C code:
>
> void *my_thread(void *ptr)
> {
>    caml_c_thread_register();
>    for(;;)
>    {
>        caml_acquire_runtime_system();
>        caml_callback(*caml_named_value("my_callback"), Val_unit);
>        caml_release_runtime_system();
>    }
>    caml_c_thread_unregister(); // I realize this will never be
> called.  I've tried without the for loop as well, same result
> }
>
> CAMLprim value caml_create_callback(value unit)
> {
>    pthread_t thread1;
>    pthread_create(&thread1, NULL, my_thread, NULL);
>    return Val_unit;
> }
>
> OCaml code:
>
> external create_callback : unit -> unit = "caml_create_callback"
>
> let my_thread () =
>    ()
>
> let _ =
>    Callback.register "my_callback" random_thread;
>    create_callback ();
>    while true do
>        ()
>    done
>
> This code will segfault immediately.  If I remove the thread_register
> functions it will run as expected.  If I try and do anything more than
> just return unit, it will segfault unless I add in some sleep
> statements.  I'm assuming that the sleep function acts as a sort of
> poor-man's thread synchronizer.  I've tried endless permutations

Maybe you are trying to call caml_c_thread_register() inside a thread
created by Caml runtime? Otherwise I cannot imagine how
caml_callback() could ever succeed without registering C-thread first.

- Dmitry Bely


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

* Re: [Caml-list] Using C threads
  2011-03-01 12:14 ` Dmitry Bely
@ 2011-03-03 22:16   ` Niki Yoshiuchi
  2011-03-03 23:03     ` Dmitry Bely
  0 siblings, 1 reply; 9+ messages in thread
From: Niki Yoshiuchi @ 2011-03-03 22:16 UTC (permalink / raw)
  To: caml-list

I figured it out so I'm posting it here for reference.
caml_c_thread_register() attempts to get the master lock, which
involves dereferencing a pointer.  That pointer is initialized by the
Thread module.  However if the OCaml code doesn't use the Thread
module that pointer is never initialized resulting in a segfault.  You
can force the initialization with something as simple as:

    ignore (Thread.self ());

Additionally, if your OCaml code doesn't use any threads (or call any
c code with a call to caml_enter_blocking_section()) then it appears
that the master lock is never released by the main thread, so the C
thread hangs in the caml_c_thread_register() call.

-Niki Yoshiuchi

On Tue, Mar 1, 2011 at 7:14 AM, Dmitry Bely <dmitry.bely@gmail.com> wrote:
> On Tue, Mar 1, 2011 at 12:56 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
>> I'm trying to call some OCaml code from a thread created in C.  I know
>> I'm supposed to call caml_c_thread_{un}register, however this pretty
>> much guarantees a segfault.  If I leave them out, my code works fine
>> so long as I don't try and do much of anything.  Here's my code
>> stripped down to the bare minimum:
>>
>> C code:
>>
>> void *my_thread(void *ptr)
>> {
>>    caml_c_thread_register();
>>    for(;;)
>>    {
>>        caml_acquire_runtime_system();
>>        caml_callback(*caml_named_value("my_callback"), Val_unit);
>>        caml_release_runtime_system();
>>    }
>>    caml_c_thread_unregister(); // I realize this will never be
>> called.  I've tried without the for loop as well, same result
>> }
>>
>> CAMLprim value caml_create_callback(value unit)
>> {
>>    pthread_t thread1;
>>    pthread_create(&thread1, NULL, my_thread, NULL);
>>    return Val_unit;
>> }
>>
>> OCaml code:
>>
>> external create_callback : unit -> unit = "caml_create_callback"
>>
>> let my_thread () =
>>    ()
>>
>> let _ =
>>    Callback.register "my_callback" random_thread;
>>    create_callback ();
>>    while true do
>>        ()
>>    done
>>
>> This code will segfault immediately.  If I remove the thread_register
>> functions it will run as expected.  If I try and do anything more than
>> just return unit, it will segfault unless I add in some sleep
>> statements.  I'm assuming that the sleep function acts as a sort of
>> poor-man's thread synchronizer.  I've tried endless permutations
>
> Maybe you are trying to call caml_c_thread_register() inside a thread
> created by Caml runtime? Otherwise I cannot imagine how
> caml_callback() could ever succeed without registering C-thread first.
>
> - Dmitry Bely
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

* Re: [Caml-list] Using C threads
  2011-03-03 22:16   ` Niki Yoshiuchi
@ 2011-03-03 23:03     ` Dmitry Bely
  2011-03-03 23:23       ` Niki Yoshiuchi
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Bely @ 2011-03-03 23:03 UTC (permalink / raw)
  To: caml-list

On Fri, Mar 4, 2011 at 1:16 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
> I figured it out so I'm posting it here for reference.
> caml_c_thread_register() attempts to get the master lock, which
> involves dereferencing a pointer.  That pointer is initialized by the
> Thread module.  However if the OCaml code doesn't use the Thread
> module

Have you specified -thread compiler option? Is it mandatory when using
system threads.

- Dmitry Bely


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

* Re: [Caml-list] Using C threads
  2011-03-03 23:03     ` Dmitry Bely
@ 2011-03-03 23:23       ` Niki Yoshiuchi
  2011-03-03 23:38         ` Dmitry Bely
  0 siblings, 1 reply; 9+ messages in thread
From: Niki Yoshiuchi @ 2011-03-03 23:23 UTC (permalink / raw)
  To: caml-list

Yes, I have (you can't use caml_c_thread_register() without it).
However it appears that the flag doesn't run the code in the module.
Nor does opening the module - only using the module seems to force the
'let _ =' code to run.

Also, I got around the hanging caml_c_thread_register() problem by
adding a select() call in the function that calls pthread_create().

On Thu, Mar 3, 2011 at 6:03 PM, Dmitry Bely <dmitry.bely@gmail.com> wrote:
> On Fri, Mar 4, 2011 at 1:16 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
>> I figured it out so I'm posting it here for reference.
>> caml_c_thread_register() attempts to get the master lock, which
>> involves dereferencing a pointer.  That pointer is initialized by the
>> Thread module.  However if the OCaml code doesn't use the Thread
>> module
>
> Have you specified -thread compiler option? Is it mandatory when using
> system threads.
>
> - Dmitry Bely
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

* Re: [Caml-list] Using C threads
  2011-03-03 23:23       ` Niki Yoshiuchi
@ 2011-03-03 23:38         ` Dmitry Bely
  2011-03-03 23:46           ` Niki Yoshiuchi
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Bely @ 2011-03-03 23:38 UTC (permalink / raw)
  To: caml-list

On Fri, Mar 4, 2011 at 2:23 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
> Yes, I have (you can't use caml_c_thread_register() without it).
> However it appears that the flag doesn't run the code in the module.

If you link your program as described in the manual:

ocamlc -thread other options unix.cma threads.cma other files
ocamlopt -thread other options unix.cmxa threads.cmxa other files

Thread.thread_initialize should be called automatically by ocaml
runtime during startup. If it's not called, something is broken in
your system. Do you have the main program in Ocaml? If not, do you
call caml_startup() from your C code?

- Dmitry Bely

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

* Re: [Caml-list] Using C threads
  2011-03-03 23:38         ` Dmitry Bely
@ 2011-03-03 23:46           ` Niki Yoshiuchi
  2011-03-04  0:17             ` Dmitry Bely
  2011-03-04  9:21             ` xclerc
  0 siblings, 2 replies; 9+ messages in thread
From: Niki Yoshiuchi @ 2011-03-03 23:46 UTC (permalink / raw)
  To: caml-list

My main program is in OCaml.  Thread.thread_initialize is only called
if you actually use the module in question.  I tested this with some
simple code:

main.ml: (ocamlc -c main.ml)

let _ = Printf.printf "Main\n"

test.ml: (ocamlc -c test.ml)

let _ = Printf.printf "Test\n"

test2.ml: (ocamlc -o test2.cma -a test2.ml)

let _ Printf.printf "Test2\n"

ocamlc test2.cma test.cmo main.cmo
./a.out
Test
Main

"Test2" never gets printed.

On Thu, Mar 3, 2011 at 6:38 PM, Dmitry Bely <dmitry.bely@gmail.com> wrote:
> On Fri, Mar 4, 2011 at 2:23 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
>> Yes, I have (you can't use caml_c_thread_register() without it).
>> However it appears that the flag doesn't run the code in the module.
>
> If you link your program as described in the manual:
>
> ocamlc -thread other options unix.cma threads.cma other files
> ocamlopt -thread other options unix.cmxa threads.cmxa other files
>
> Thread.thread_initialize should be called automatically by ocaml
> runtime during startup. If it's not called, something is broken in
> your system. Do you have the main program in Ocaml? If not, do you
> call caml_startup() from your C code?
>
> - Dmitry Bely
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

* Re: [Caml-list] Using C threads
  2011-03-03 23:46           ` Niki Yoshiuchi
@ 2011-03-04  0:17             ` Dmitry Bely
  2011-03-04  9:21             ` xclerc
  1 sibling, 0 replies; 9+ messages in thread
From: Dmitry Bely @ 2011-03-04  0:17 UTC (permalink / raw)
  To: caml-list

I see. Not ocaml thread function is used so threads.cma is not linked.
You are right. Probably this deserves a bug report:
caml_c_thread_register() can check that no master lock still exists
and initialize it if necessary.

- Dmitry Bely

On Fri, Mar 4, 2011 at 2:46 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
> My main program is in OCaml.  Thread.thread_initialize is only called
> if you actually use the module in question.  I tested this with some
> simple code:
>
> main.ml: (ocamlc -c main.ml)
>
> let _ = Printf.printf "Main\n"
>
> test.ml: (ocamlc -c test.ml)
>
> let _ = Printf.printf "Test\n"
>
> test2.ml: (ocamlc -o test2.cma -a test2.ml)
>
> let _ Printf.printf "Test2\n"
>
> ocamlc test2.cma test.cmo main.cmo
> ./a.out
> Test
> Main
>
> "Test2" never gets printed.
>
> On Thu, Mar 3, 2011 at 6:38 PM, Dmitry Bely <dmitry.bely@gmail.com> wrote:
>> On Fri, Mar 4, 2011 at 2:23 AM, Niki Yoshiuchi <aplusbi@gmail.com> wrote:
>>> Yes, I have (you can't use caml_c_thread_register() without it).
>>> However it appears that the flag doesn't run the code in the module.
>>
>> If you link your program as described in the manual:
>>
>> ocamlc -thread other options unix.cma threads.cma other files
>> ocamlopt -thread other options unix.cmxa threads.cmxa other files
>>
>> Thread.thread_initialize should be called automatically by ocaml
>> runtime during startup. If it's not called, something is broken in
>> your system. Do you have the main program in Ocaml? If not, do you
>> call caml_startup() from your C code?
>>
>> - Dmitry Bely
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa-roc.inria.fr/wws/info/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>


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

* Re: [Caml-list] Using C threads
  2011-03-03 23:46           ` Niki Yoshiuchi
  2011-03-04  0:17             ` Dmitry Bely
@ 2011-03-04  9:21             ` xclerc
  1 sibling, 0 replies; 9+ messages in thread
From: xclerc @ 2011-03-04  9:21 UTC (permalink / raw)
  To: Caml List; +Cc: xclerc Clerc


Le 4 mars 2011 à 00:46, Niki Yoshiuchi a écrit :

> My main program is in OCaml.  Thread.thread_initialize is only called
> if you actually use the module in question.  I tested this with some
> simple code:
> 
> main.ml: (ocamlc -c main.ml)
> 
> let _ = Printf.printf "Main\n"
> 
> test.ml: (ocamlc -c test.ml)
> 
> let _ = Printf.printf "Test\n"
> 
> test2.ml: (ocamlc -o test2.cma -a test2.ml)
> 
> let _ Printf.printf "Test2\n"
> 
> ocamlc test2.cma test.cmo main.cmo
> ./a.out
> Test
> Main
> 
> "Test2" never gets printed.

Seems to work with "ocamlc -linkall test2.cma test.cmo main.cmo".


Regards,

Xavier Clerc



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

end of thread, other threads:[~2011-03-04  9:21 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-02-28 21:56 [Caml-list] Using C threads Niki Yoshiuchi
2011-03-01 12:14 ` Dmitry Bely
2011-03-03 22:16   ` Niki Yoshiuchi
2011-03-03 23:03     ` Dmitry Bely
2011-03-03 23:23       ` Niki Yoshiuchi
2011-03-03 23:38         ` Dmitry Bely
2011-03-03 23:46           ` Niki Yoshiuchi
2011-03-04  0:17             ` Dmitry Bely
2011-03-04  9:21             ` xclerc

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).