Saturday, April 28, 2018

Lock Free queue with CAS (compare and swap)


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