cur_slot / size; cur_slot = cur_slot % size; while (true) { uint64_t flag = slot[cur_slot].flag; if (flag % 2 == 0 || flag / 2 != order) { //if (slot[cur_slot].flag % 2 == 0 || slot[cur_slot].flag / 2 != order) { this_thread::yield(); } else { int ret = slot[cur_slot].key; slot[cur_slot].flag++; return ret; } } } Commented out if statement has potential hazard(unexpected behavior). Queue will suffer infinite loop if slot[cur_slot].flag's value has been modified by other dequeuing thread during the execution of if statement. The full code can be found here Cause of Possible Infinite Loop in Wait-free Queue void enqueue(int key) { uint64_t cur_slot = rear++; int order = cur_slot / size; cur_slot = cur_slot % size; while (true) { uint64_t flag = slot[cur_slot].flag; if (flag % 2 == 1 || flag / 2 != order) { this_thread::yield(); } else { slot[cur_slot].key = key; slot[cur_slot].flag++; break; } } }
4 I will briefly demonstrate possible hazard scenario with 4 threads. Assume all threads already called enqueue/dequeue function. Their cur_slot value is showed in gray box. Let's ignore all other function calls between them. Current running thread & code section will be highlighted by red box. int dequeue() { uint64_t cur_slot = front++; int order = cur_slot / size; cur_slot = cur_slot % size; while (true) { uint64_t flag = slot[cur_slot].flag; if (flag % 2 == 0 || flag / 2 != order) { //if (slot[cur_slot].flag % 2 == 0 || slot[cur_slot].flag / 2 != order) { this_thread::yield(); } else { int ret = slot[cur_slot].key; slot[cur_slot].flag++; return ret; } } } void enqueue(int key); ... ... 4 9 9 Assume size = 5 enq(▪) deq() enq(▪) deq()