Hatena::ブログ(Diary)

Oh, you `re no (fun _ → more) このページをアンテナに追加 RSSフィード

Ah well, a dromedary has one hump and a caml has reference cells, buffers, and a garbage collector.

2010-03-09

caml_{enter,leave}_blocking_section

What are caml_{enter,leave}_blocking_section? They are not documented in the OCaml reference manual, but are very important if you tweak C code in multi-thread OCaml environment:

Jacque Garrigue wrote:

With posix threads (or windows threads), every caml thread is mapped

to a posix thread, but there is a global mutex which any caml thread

must obtain before running. This makes sure for instance that memory

allocation and GC work properly.

So no more than one caml thread may run simultaneously, and you don't

gain from multiple CPUs.

However, contrary to vmthreads, this restriction only applies while

executing caml code. If you call some C function, you may choose to

first release the global lock (caml_enter_blocking_section), letting

other caml threads work while you are on the C side. Don't forget to

call lock again (caml_leave_blocking_section) when returning, or you

will crash very soon.

http://groups.google.com/group/fa.caml/browse_thread/thread/4029e626205820b9/3671a04944223bee?lnk=gst&q=caml_enter_blocking_section#3671a04944223bee

Sounds odd (a blocking section unblocks other threads!), but,

  • caml_enter_blocking_section : release the global lock in OCaml runtime.
  • caml_leave_blocking_section : lock it again.
  • In the section, some other threads may work simultaneously with the current thread.

Yes, it is true, but be careful, when your C code accesses OCaml values (alloc, reading pointers, etc) before entering the section. Once after the lock is released, some other OCaml threads are executed, and there is a chance of GC. This makes your OCaml related pointer values no longer reliable!!

Actually Francois Rouaix has pointed it out long ago:

When you want to be able to switch threads while in C-code, or handle

signals.

However, my understanding is that the code in the section must not

access anything in the Caml heap.

On Jan 16, 2006, at 7:33 AM, Bauer, Christoph wrote:

> Hi,

>

> when do I have to call the functions

> caml_enter_blocking_section ()

> and

> caml_leave_blocking_section ()

> in my C-stub code?

>

> Thanks,

>

> Christoph Bauer

> Dipl. Inf.

http://groups.google.com/group/fa.caml/browse_thread/thread/fd6c8ec4f51c0fc5/3ab73788b5f142a1?lnk=gst&q=caml_enter_blocking_section#3ab73788b5f142a1

Actually we can see such an example of caml_{enter,leave}_blocking_sections in byterun/sys.c

CAMLprim value caml_sys_open(value path, value vflags, value vperm)
{
  CAMLparam3(path, vflags, vperm);
  int fd, flags, perm;
  char * p;

  p = caml_stat_alloc(caml_string_length(path) + 1);
  strcpy(p, String_val(path));
  flags = caml_convert_flag_list(vflags, sys_open_flags);
  perm = Int_val(vperm);
  /* open on a named FIFO can block (PR#1533) */
  caml_enter_blocking_section();
  fd = open(p, flags, perm);
  caml_leave_blocking_section();
  caml_stat_free(p);
  if (fd == -1) caml_sys_error(path);
#if defined(F_SETFD) && defined(FD_CLOEXEC)
  fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif
  CAMLreturn(Val_long(fd));
}

Here, the open syscall is in the section, so that it may not block the other thread; open is a lengthyoperation in certain circumstances. It uses the file path given from the OCaml(path), but since path is in the OCaml heap, we cannot use it safely. The code escapes the contents of path to p, a C-malloc'ed memory before entering the section. Beware, this code demonstrates even CAMLparam'ed pointers may become unreliable due to the GC once we enter the section!!

There may be some other informative posts found in caml-list:

http://groups.google.com/group/fa.caml/search?group=fa.caml&q=caml_enter_blocking_section&qt_g=Search+this+group

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/camlspotter/20100309/1268111257