マルチスレッド

超スマートポインタをマルチスレッド対応にしようと思い立った。あまりマルチスレッドの経験はないのだけど、オブジェクトの所有権が曖昧になるというのは特にマルチスレッドに多いことなので必要だろうということだ。
マルチスレッド対応とはつまり、クリティカル・セクションを排他保護するということだ。超ス(略では参照カウントの上げ下げと循環検出を保護すれば良いだろう。だからといって全て保護したのでは実行効率が悪化するのが目に見えている。どうすれば良いのか考えてみた。

  • 循環検出と循環検出は排他する。
  • ポインタaの参照上げ下げとaの参照上げ下げは排他する。
  • 異なるポインタa, bについて、aの参照上げ下げとbの参照上げ下げは排他しない。
  • ポインタaの参照上げ下げと循環検出は排他する?

とりあえず、各ポインタについては単純にポインタごとにmutexを持って排他すれば良さそうだ。
循環検出についてはどうするべきだろうか。循環検出の内部でもaの参照上げ下げが発生するため、単純な排他は出来ないと考えられる。いや、循環検出からaの参照上げ下げをするときだけロックを掛けなければ良いのか。

template<typename T>
class smart_ptr {
private:
  static rwlock global;
public:
  void collect_cycles() {
    global.wrlock();
    //ここではinner_increment(), inner_decrement()を使う。
    global.unlock();
  }
private:
  T* ptgt;
  mutex local;
public:
  void increment() {
    global.rdlock();
    local.lock();
    inner_increment();
    local.unlock();
    global.unlock();
  }
  void decrement() {
    global.rdlock();
    local.lock();
    inner_decrement();
    local.unlock();
    global.unlock();
  }
}

もっとこまめに排他した方が良いのかもしれないけれど、まずは参照実装としてこの程度の排他で進めよう。

      • -

root_setの排他を忘れていた。STLは基本的にMT安全ではないのだっけ。MT安全にすると実行コストが上がるのだからオプションにするべきだとは思うけども。