caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Markus Mottl <markus.mottl@gmail.com>
To: EL CHAAR RABIH <RABIH.EL-CHAAR@sgam.com>
Cc: OCaml <caml-list@inria.fr>
Subject: Re: [Caml-list] Re: C-threads & callbacks vs camljava in a multithrea ded context
Date: Mon, 7 Mar 2005 11:22:06 -0500	[thread overview]
Message-ID: <20050307162206.GA18087@quant3.janestcapital.quant> (raw)
In-Reply-To: <71A291D8E360AF4EA6FFFAF9CAD136CA03773583@FR-MAILBOX2.fr.sgam.socgen> <71A291D8E360AF4EA6FFFAF9CAD136CA03773585@FR-MAILBOX2.fr.sgam.socgen>

Hi,

sorry for the delay, but I was extremely busy answering a huge backlog
of mails recently.

On Wed, 23 Feb 2005, EL CHAAR RABIH wrote:
> I sent today a mail concenrning external threads (java threads) and caml.
> When looking inside the caml-list, i came up upon your mail, which attracted
> my attention.
> 
> My goal is to try and switch the jvm thread into a caml thread.
> 
> Is it possible to have your opinion upon my post "Using camljava library in
> a multithreaded context"?
> Is it also possible to have a small example (C and ocaml) realising this
> coordination issue ?

Unfortunately, I have no experience with Java so I cannot tell you
whether there is a way to let Java-threads migrate to OCaml.

My C-solution, which seems to work very well in practice, looks roughly
as follows:

  pthread_mutex_t cb_act_mtx;
  pthread_cond_t cb_act_cnd;
  value *cb_act;

  pthread_mutex_t cb_res_mtx;
  pthread_cond_t cb_res_cnd;

The first mutex and condition variable protect "cb_act", the callback
action to be performed.

If there is a C-thread that wants to call OCaml, it calls the following
function/method (it's actually C++):

  void do_cb(value *action)
  {
    pthread_mutex_lock(&cb_act_mtx);
      cb_act = action;
      pthread_cond_signal(&cb_act_cnd);
    pthread_mutex_unlock(&cb_act_mtx);

    pthread_mutex_lock(&cb_res_mtx);
      while (not cb_res_avail) pthread_cond_wait(&cb_res_cnd, &cb_res_mtx);
    pthread_mutex_unlock(&cb_res_mtx);

    cb_res_avail = false;
  }

Depending on the kind of action that should be performed, an OCaml-thread
that has previously gone into C-land will eventually convert C-data to
OCaml-values before performing the callback.  After returning it will
signal the C-thread that a result is available (or simply that it has
completed the job).  The OCaml-thread has to perform all the conversions,
because the C-thread must not call the GC.  Our C-function, in which
the OCaml-thread waits for callbacks + associated data looks as follows:

  virtual value handle_cbs()
  {
    while (true) {
      caml_enter_blocking_section();
        pthread_mutex_lock(&cb_act_mtx);
          while (cb_act == NULL)
            pthread_cond_wait(&cb_act_cnd, &cb_act_mtx);
        pthread_mutex_unlock(&cb_act_mtx);
      caml_leave_blocking_section();

      if (cb_act == &v_OnRecordUpdateCallback)
        caml_callback(*cb_act,
                      vrc_make(rup, free_record_update, lev1_GC_setting));
      else if (cb_act == &v_Terminate) {}
      else cb_sc = caml_callback(*cb_act, Val_int(cb_sc));

      pthread_mutex_lock(&cb_res_mtx);
        cb_act = NULL;
        cb_res_avail = true;
        pthread_cond_signal(&cb_res_cnd);
      pthread_mutex_unlock(&cb_res_mtx);

      if (cb_act == &v_Terminate) return Val_unit;
    };

    return Val_unit;  // we should never get here
  }

In OCaml you just need to specify the external function that the
OCaml-thread should call:

  external handle_cbs : t -> unit = "activ_handle_cbs_stub"

Then do something like the following at startup:

  let wrap_handle_cbs () =
    try handle_cbs cgc
    with exc ->
      (match exc with
      | Status sc ->
          eprintf "Activ-exception: Status %s\n" (Status_code.to_string sc)
      | FieldStatus fs ->
          eprintf
            "Activ-exception: FieldStatus %s\n" (Field_status.to_string fs)
      | _ ->
          eprintf "Exception escaping callback: %s\n" (Printexc.to_string exc)
      );
      exit 2 in
  ignore (Thread.create wrap_handle_cbs ());

I hope that this info is enough so that you can make OCaml- and C-threads
interact smoothly.

Regards,
Markus

-- 
Markus Mottl    markus.mottl@gmail.com    http://www.ocaml.info


  parent reply	other threads:[~2005-03-07 16:22 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-23 14:35 Using camljava library in a multithreaded context EL CHAAR RABIH
     [not found] ` <71A291D8E360AF4EA6FFFAF9CAD136CA03773585@FR-MAILBOX2.fr.sgam.socgen>
2005-03-07 16:22   ` Markus Mottl [this message]
2005-03-07 16:47 ` Xavier Leroy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20050307162206.GA18087@quant3.janestcapital.quant \
    --to=markus.mottl@gmail.com \
    --cc=RABIH.EL-CHAAR@sgam.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).