2

アトミックを使用したウェイトフリー キューの C++ 実装を探していたところ、Boost.Atomic の例が見つかりました。

template<typename T>
class waitfree_queue {
public:
  struct node {
    T data;
    node * next;
  };
  void push(const T &data)
  {
    node * n = new node;
    n->data = data;
    node * stale_head = head_.load(boost::memory_order_relaxed);
    do {
      n->next = stale_head;
    } while (!head_.compare_exchange_weak(stale_head, n, boost::memory_order_release));
  }

  node * pop_all(void)
  {
    T * last = pop_all_reverse(), * first = 0;
    while(last) {
      T * tmp = last;
      last = last->next;
      tmp->next = first;
      first = tmp;
    }
    return first;
  }

  waitfree_queue() : head_(0) {}

  // alternative interface if ordering is of no importance
  node * pop_all_reverse(void)
  {
    return head_.exchange(0, boost::memory_order_consume);
  }
private:
  boost::atomic<node *> head_;
};

int main() {
// pop elements
waitfree_queue<int>::node * x = q.pop_all()
while(x) {
  X * tmp = x;
  x = x->next;
  // process tmp->data, probably delete it afterwards
  delete tmp;
}

}

ブースト公式サイトでの例

boost を std に置き換え、MSVC 2012 でコンパイルしました。コンソールに次のメッセージが表示されてクラッシュします。

Assertion failed: _Order2 != memory_order_release, file c:\program files (x86)\m
icrosoft visual studio 11.0\vc\include\xxatomic, line 742

元のブーストをコンパイルすると、クラッシュして実行されます。

Boost.Atomic または MSVC のアトミック実装のバグですか?

4

1 に答える 1

1

MSVC 実装のバグのようです。Order2であるため、アサーションは失敗しますmemory_order_release。ただし、ここに記載されているように(これは C++ 標準と同じです) (強調は私のものです):

3 パラメーターのオーバーロードは、success_order==order および failure_order==order を使用した 4 パラメーターのオーバーロードと同等ですが、order が std::memory_order_acq_rel の場合、failure_order は std::memory_order_acquire であり、order が std::の場合は異なります。 memory_order_release の場合、 failure_order は std::memory_order_relaxedです。

つまり、として渡したので、あなたのケースでは 4 パラメーターのオーバーロードに対応しているOrder2 必要があり ます。これは、バグである MSVC の実装には当てはまりません。可能であれば、バグとして報告してください。std::memory_order_relaxedmemory_order_releaseorder

于 2013-02-10T21:39:21.087 に答える