MTライブラリの難しさ

ここ数日TOPPERS/JSP for BFのライブラリと向き直って頭を抱えています。現在のリリースでは暫定的にBF533のVDKライブラリを使用しています。しかしながら、実際のところ現在のライブラリの使い方ではシングル・スレッド(ST)ライブラリと同じでしかありません。

MTライブラリ

MTライブラリの難しさは、本来C/C++にMTの概念がないことにあります。例えば、errno変数1つをとってもそうです。math.hで宣言される関数を使用すると、エラーが発生したときにerror.hで宣言されるerrno変数にエラーコードが書き込まれます。errno変数には常に最後にエラーを発生した関数のエラーコードが保存されています。
さて、errnoがST環境で使われているなら問題ありません。MT環境だとどうなるでしょうか。errnoを読み込んでいる間に他のスレッドがerrnoを変更するとどうでしょう。
「ロックすればいい」
そのとおりです。ロックすれば少なくとも書き込みと読み込みがきちんと分離されます。しかし、errnoに入っているエラーコードは誰のエラーコードでしょうか。

  • errnoには同じスレッドで実行された関数の結果だけが反映されるべきである。
  • errnoにはスレッド全部の最新のエラーコードが反映されるべきである。

後者なら簡単です。しかしそれはC/C++設計者がerrno変数に期待したことでしょうか。
VDKライブラリは前者の立場をとります。そしてそのための仕掛けを埋め込んでいます。しかしながら埋め込まれた仕掛けはライブラリとしてのみ供給されており、しかもロック機構としてVDKのセマフォを使っています。
その仕掛けを書き直してTOPPERS/JSPセマフォを使うように変更するのが一番簡単です。しかしながらこれってNDAなしで情報開示してくれるのかな。ま、聞いてみます。

STライブラリ

仮に先のerrnoの解釈を前者とすると、あるいは前者でよいと妥協すると、STライブラリを使えるかもしれません。いくつかのソースを覗き見たりトレースしてみると、ある種の関数は原始的なロックがかけられています。であれば、STライブラリをそのままTOPPERS/JSPで使うのも手です。
追記:後から調べてみて、全部の関数にロックがかかっているわけではないとわかりました。

Interrupt Safe

さて、Thread Safeと言う言葉があります。上で説明したように複数スレッドでライブラリを共用しても安全に作っているライブラリはThread Safeとよびます。ところが、Interrupt Safeと言う言葉があることは知りませんでした。そして

VisualDSP++のライブラリはMT/STを問わずInterrupt Safeではない

と言うこともはじめて知りました。これはびっくりです。
ある種のライブラリ関数はInterrupt Safeです。しかしerrno変数のような大域変数を扱うよう設計されたC/C++関数はVisualDSP++ではInterrupt Safeではないとされ、割り込みハンドラとアプリケーションの双方で使ってはならないとされています。一方でDSPライブラリの関数はInterrupt Safeです。
これまで意識せずに使っていたのでちょっと冷や汗を書いた瞬間でした。