0

ロックフリーの単一リンクリストの実装を作成するために運を試しています。

typedef _Atomic struct _node
  {
    void *data;
    struct _node *next;
  } Node;

これは _Atomic を持つ構造体のすべてのメンバーもアトミックにしますか?

void add_head ( Linked_list* list, void* data )
{
  if ( debugging )
  {
      printf ( "%s\n", __func__ );
  }
  Node *node = ( Node* ) calloc ( 1, sizeof (Node ) );
  //init_node_mutex(node);
  //lock_node_mutex(node);
  atomic_exchange ( &node->next, NULL );
  atomic_exchange ( &node->data, data );

  if ( list->head == NULL )
  {
      Node* the_tail = atomic_load ( &list->tail );
      //  lock_node_mutex ( the_tail );
      atomic_exchange ( &node->next, NULL );
      atomic_compare_exchange_weak ( &list->tail, the_tail, node );

      //unlock_node_mutex ( the_tail );

  }
  else
  {

      Node* the_next = atomic_load ( &node->next );
      // lock_node_mutex ( the_next );
      atomic_compare_exchange_weak ( &node->next, the_next, list->head );
      // unlock_node_mutex ( the_next );
  }

  Node* the_head = atomic_load ( & list->head );
  //lock_node_mutex ( the_head );
  atomic_store ( &list->head, node );
  atomic_store ( &list->current, node );
  //unlock_node_mutex ( the_head );
  //unlock_node_mutex(node);
  atomic_fetch_add ( &list->size, 1 );
}

使用法はatomic_loadとatomic_storeが正しいですか?

4

2 に答える 2

2

わかりました、これを「コメント」として投稿するか「回答」として投稿するかについて議論しましたが、ここでは一文無しにします。

私の本能は、「あなたが実行している個々の操作が「アトミック」であるかどうかは、実際には問題ではありません。なぜなら、あなたは自分が何であるかを達成するために、多くの操作を連続して実行しているからです。これらの個々のステップが「アトミック」であっても、操作全体はそうではありません。

「アトミック」操作とは、x86のプレフィックスや big-iron の「compare-and-swap」命令などの特殊なマシン命令を使用して、他のCPU (またはコア)が干渉しないように単一の操作を実行する操作です。その1回の操作で。LOCK

しかし、アトミックであろうとなかろうと、「単一の命令」でやろうとしていることを行うことはできません。

したがって、現在のコースを放棄し、それらの「ミューテックス」呼び出しを元に戻し、「アトミック」を削除することを心からお勧めします。コード (および、このようなすべてのコード) には、これらのミューテックスが必要です。私の意見では、あなたは行き​​止まりの路地で白いウサギを追いかけています。

(ちなみに、「ミューテックス」操作は、これらの「アトミック命令」を非常にうまく利用することがあるため、恐れているよりもかなり効率的です。)

于 2016-07-12T00:02:09.850 に答える