do {
p = ctx->tail;
if ( __sync_bool_compare_and_swap(&ctx->tail, p, tmpnode)) {
p->next=tmpnode;
break;
}
} while(1);
First a temporary variable, p
, is assigned the same value of the tail of our queue. In this case ctx
is short for “queue context”. Next we want to add our new node tmpnode
to the end of our queue (make it the tail). If two threads are trying to do this at the same time, then one of them will succeed and one of them will fail. If the compare operation fails then the enqueue action will immediately loop again, trying to do another compare and swap operation, with the updated tail value. It will do this until it is successful, or until the heat death of the universe.
When the compare and set operation is successful, it means that we were able to change the value of the tail
. The next line updates the previous tail’s next
pointer to point to our new node. We don’t need to do this via a compare and set atomic operation, because if anyone else is trying to modify the the tail, they failed (or otherwise our compare would have failed). The break
at the end exits the loop
https://schneems.com/2017/06/28/how-to-write-a-lock-free-queue/
https://www.codeproject.com/Articles/153898/Yet-another-implementation-of-a-lock-free-circular
No comments:
Post a Comment