OCamlの関数をCのスレッドで呼ぶ方法がわかった

困ってる人を見かけたのでトラックバック
ちょうど最近、GLCamlのSDL_audioを使えるようにしたところです。使うアテもなかったのですが、ちょうど良かったです。

https://github.com/ytomino/glcaml/blob/master/lib/sdl_audio_stub.c

caml_c_thread_registerでスレッド登録。同じスレッドから何度呼んでも大丈夫です。(スレッドプールから呼ばれるコールバックの場合、解除できるタイミングがありませんが、まあSDL_audioならスレッド終了時=プログラム終了時でしょうからたぶん大丈夫?)

続けてcaml_leave_blocking_sectionを呼んでOCamlの実行権を獲得します。blocking sectionというのはOCamlの外で待ちが入る処理のことで、その間OCamlは他のスレッドを実行しています。blocking sectionからleaveする=OCaml側の処理に入る、です。その状態でOCamlの関数を呼べばいいです。最後にenter〜で他のスレッドにOCamlの実行権を明け渡します。

当たり前ですが、メインスレッドからもどこかでcaml_enter_blocking_section/caml_leave_blocking_sectionしないと、他のスレッドは延々待ちつづけることになります。SDLならSDL_WaitEventによるイベント待ちや画面描画時のVSYNC待ちをblocking sectionと見なすのが妥当でしょう。

加えて、初期化のためにどっかでThreadモジュールの関数(なんでもいい)を呼ばないといけません。私のバージョンではsdl_audio.mlの最後でちょろっと呼んでます。(C側でcaml_c_thread_initを呼ぶのでもいいような気がするのですが、ダメでした。OCaml側で追加の初期化が何かなされてるのでしょう、たぶん。知らんです。ソース読んでないです)

っていうかむしろhttps://github.com/einars/glcamlを使ってforkしていろいろ直してください。(宣伝)