Verification Challenges
"Analyze This" II
Verify that the following implementation of a non-blocking queue algorithm is correct. This non-blocking queue is taken from Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms by Maged M. Michael and Michael L. Scott (PODC'96).
The first (easier) challenge is to verify that the implementation satisfies some structural properties (taken from the manual proof in the PODC'96 paper). The properties to be verified are:
P1 The linked list is always connected.
P2 Nodes are only inserted after the last node of the linked list.
P3 Nodes are only deleted from the beginning of the linked list.
P4 Head always points to the first node in the linked list.
P5 Tail always points to a node in the linked list.
The next challenge is to verify that the implementation is linearizable.
// Non Blocking Queue
class NonBlockingQueue {
private QueueItem Head;
private QueueItem Tail;
...
NonBlockingQueue() {
node = new QueueItem()
node.next.ref = NULL
this.Head = this.Tail = node
}
public void enqueue(Object value) {
e_1 node = new QueueItem()
e_2 node.value = value
e_3 node.next.ref = NULL
e_4 while(true) { // Keep trying until done
e_5 tail = this.Tail
e_6 next = tail.ref.next
e_7 if (tail == this.Tail) {
e_8 if (next.ref == NULL) {
e_9 if CAS(tail.ref.next, next, <node, next.count+1>) {
e_10 break // Enqueue is done. Exit loop
e_11 }
e_12 } else {
e_13 CAS(this.Tail, tail, <next.ref, tail.count+1>)
e_14 }
e_15 }
e_16 }
e_17 CAS(this.Tail, tail, <node, tail.count+1>)
e_18 }
public Object dequeue() {
Object result = null
d_1 while(true) {
d_2 head = this.Head
d_3 tail = this.Tail
d_4 next = head.next
d_5 if (head == this.Head) {
d_6 if (head.ref == tail.ref) {
d_7 if (next.ref == NULL) { // is empty?
d_8 return result
d_9 }
d_10 CAS(this.Tail, tail, <next.ref, tail.count+1>)
d_11 } else { // No need to deal with Tail
d_12 result = next.ref.value
d_13 if CAS(this.Head, head, <next.ref, head.count+1>) {
d_14 break // dequeue done
d_15 }
d_16 }
d_17 }
d_18 }
d_19 free(head.ref) // safe to free old dummy node
d_20 return result
d_21
} }
|
Where the implementation of QueueItem is given below
// QueueItem.java
class QueueItem {
public QueueItem next;
public Object value;
...
}
|
We showed some version of verification of the structural properties in Automatically Verifying Concurrent Queue Algorithms, Yahav E. and Sagiv M., SoftMC 2003, [bib][abstract][ps][pdf][slides]
We investigated verification of linearizability for such algorithms in Comparison under Abstraction for Verifying Linearizability, Amit D., Rinetzky N. , Reps T., Sagiv M. and Yahav E., CAV'07: Computer Aided Verification 2007, [bib] [abstract] [ps] [pdf] [slides]
We also showed how to systematically derive linearizable concurrent data-structures from a sequential implementation in Deriving Linearizable Fine-Grained Concurrent Objects, Vechev M., Yahav E., PLDI '08: ACM SIGPLAN 2008 Conference on Programming Language Design and Implementation., [bib] [abstract] [pdf] [slides]