2002/02/20の続き。
ところが、これだけでは実用的には使い物にならない。というのは、とっても遅いから。
STLportのWindows CE用のセッティングでは、_STLP_USE_MALLOCというフラグが自動的に立てられるようになっているのだけれど、このセッティングだと、STLがメモリを確保するときにmallocを呼び出す。CEのmallocの実装はLocalAllocを直接呼び出しているんじゃないかと思えるほど遅い。よって、std::vectorを伸張するたびにそんな遅いメモリアロケーション処理が行われると実用にならないくらい遅くなる。
というわけで、_STP_USE_MALLOCをセッティングから削る。さらに、_STP_USE_NEWALLOCも削る。このようにすると、通常のアロケータが使われるようになる。通常のアロケータは、固定長メモリの配列を使ったアロケータで、スレッドの排他処理もスピンロックを使っているために結構速い。
ところが、これを使うようにするとちょっと問題が発生する。と言うのは上に書いたようにスピンロックで排他制御をしているのだけれど、ロックの解除は基本どおりデストラクタで行われている。つまり、ロックを確保している間にSEH例外が投げられるとロックを確保したままになってしまう。
なので、そのメモリを確保しているところ(__node_alloc::S_chunk_alloc)に手を入れて、_stlp_chunk_mallocの呼び出し(最終的には__stl_newの呼び出しを経由して::operator newを呼び出す)を__tryと__exceptで括って、__except側に処理が移ったらデストラクタを明示的に呼び出してロックを開放することにする。
これで一応それなりのパフォーマンスでstd::vectorと各種アルゴリズムが使えるようになったはず。
つづく(かも)。