clSetEventCallback()を正しく使いたい(書きかけ)

http://www.khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clSetEventCallback.html
これのコールバック(pfn_event_notify)正しく実装するの不可能では?という気がした



経緯 :
https://twitter.com/tanakmura/status/399251693092605952
https://twitter.com/tanakmura/status/399252471903567872
https://twitter.com/tanakmura/status/399252550756487168
https://twitter.com/tanakmura/status/399253075396788224

khronos.org/registry/cl/sdk/1.1/docs/man/xhtml/clSetEventCallback.html … これ正しく使うの不可能な気がする。

どうやって非同期で呼ばれるかが実装依存になってる。考えられるのは、
(1) Windows User Mode APCみたいなの : ブロックするシステムコールで呼ばれる
(2) POSIX SIGNALみたいなの : いつでも非同期で飛んでくる
(3) 別スレッドから呼ばれる
だが、
(1) の場合ビジーループでデバイスの完了を待つみたいな処理を入れるとデッドロックする
(2) の場合Mutex入れるとデッドロックする
(3) Mutex入れないとレースコンディション発生する
で、 (2) と (3) を両方起こさないようになんか処理するの無理だと思う。


複数platform の OpenCL を動かしたいとする(NVIDIA GPUIntel CPUみたいな)。
この時、複数デバイスを同期するためのスケジューラみたいなのが必要になる。それほど複雑ではないので、キューが繋がってて、それでやりとりする実装にしよう。


(あとで図を入れる)


僕は、ちょっとイベント処理するためだけに専用スレッド立ち上げるとか好きではないので、これをclSetEventCallback()を使ってなんとかしたいと考えた。
clSetEventCallbackは、eventとそのevent発生時に呼ばれる関数を関連付けるAPI

上の図でいう、notify complete の処理は、これで実装できるわけだ。


ところが、clSetEventCallbackの注意として、コールバックは非同期に呼ばれるかもしれないから、スレッドセーフにしろ、と書かれてあるのだけど、

This callback function may be called asynchronously by the OpenCL implementation. It is the application's responsibility to ensure that the callback function is thread-safe.

これ、非同期の呼びかたの実装方法が決まってないから、正しくスレッドセーフに実装するの無理だと思った、というのが言いたいことだった。


ぱっと思い付く非同期実装としては、シグナルとスレッドがあるが(上のtweetでは、Windows User Mode APCとか書いてるが、忘れてもいいので以後特に言及しない)、シグナルから呼ばれても大丈夫 && スレッドセーフにするの不可能だから、


(…と、ここまで書いてそもそもマルチスレッド関係無く Async-signal-safe 実装するの相当難易度高いのだから、clSetEventCallbackは別スレッドから呼ばれることを明記すべきという問題な気がしてきたな。もうちょっと考える)