I am studying Michael & Scott's lock-free queue algorithm and trying to implemented it in C++.
But I produced a race in my code and think there may be a race in the algorithm.
I read the paper here: Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms and the original Dequeue pseudo-code is as following:
dequeue(Q: pointer to queue_t, pvalue: pointer to data type): boolean
D1: loop // Keep trying until Dequeue is done
D2: head = Q->Head // Read Head
D3: tail = Q->Tail // Read Tail
D4: next = head.ptr->next // Read Head.ptr->next
D5: if head == Q->Head // Are head, tail, and next consistent?
D6: if head.ptr == tail.ptr // Is queue empty or Tail falling behind?
D7: if next.ptr == NULL // Is queue empty?
D8: return FALSE // Queue is empty, couldn't dequeue
D9: endif
// Tail is falling behind. Try to advance it
D10: CAS(&Q->Tail, tail, <next.ptr, tail.count+1>)
D11: else // No need to deal with Tail
// Read value before CAS
// Otherwise, another dequeue might free the next node
D12: *pvalue = next.ptr->value
// Try to swing Head to the next node
D13: if CAS(&Q->Head, head, <next.ptr, head.count+1>)
D14: break // Dequeue is done. Exit loop
D15: endif
D16: endif
D17: endif
D18: endloop
D19: free(head.ptr) // It is safe now to free the old node
D20: return TRUE // Queue was not empty, dequeue succeeded
In my view, the race is like this:
head.ptr->next
, but as head.ptr
is already freed by Thread 1, crash happens.And my C++ code really always crashes at D4 for Thread 1.
Can anyone please point out my mistake and give some explanation ?
The Michael reaction is a nucleophilic addition reaction involving the addition of a carbanion (or any other suitable nucleophile) to an 𝛼,𝛽-unsaturated carbonyl compound that contains a functional group which is electron-withdrawing in nature.
The name first appears in the Hebrew Bible in the Book of Numbers, 13:13 where Sethur the son of Michael is one of 12 spies sent into the Land of Canaan. Michael is the name of an archangel in the Book of Daniel 12:1.
Michael first appeared in the Old Testament book of Numbers. This ubiquitous boy 's name is more than 2,500 years old – one of the oldest names still in common use today. Michael is also an archangel (an angel of high rank) who appears in the Hebrew Bible, the New Testament, and the Quran.
The Michael reaction works best with particularly acidic enolate donors such as malonic esters, β-keto esters, ect. Enolates which are weaker acids tend to undergo nucleophilic addition to the carbonyl rather than conjugate addition.
Thank you, very interesting subject! It's definitely looks like a bug, but one of the authors of the paper assert that their free() is not normal free() we all live with, but some magic free(), so there is no bug. Fantastic.
See http://blog.shealevy.com/2015/04/23/use-after-free-bug-in-maged-m-michael-and-michael-l-scotts-non-blocking-concurrent-queue-algorithm/
Hope no one put this into production without thorough analysis.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With