TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: A A A AAA A A A AA...

Preview:

Citation preview

Proving that non-blocking algorithms don't block

Alexey GotsmanUniversity of Cambridge

Joint work with Byron Cook, Matthew Parkinson, and Viktor Vafeiadis

Proving that non-blocking algorithms don't block

Automatically proving liveness properties of non-blocking concurrent algorithms

Stay awake: nice links between programming, logic, and automatic verification Pick a class of programs Pick an appropriate logic Observe that proofs are simple and follow the same pattern Infer proofs automatically

Best of both worlds: automatic tool + understanding of the algorithms

Coarse-grained locking

Top

Inefficient as only onethread operates on the

list at a time

42 13 1 4 NULL

Non-blocking concurrency

Multiple threads operating on the data structure at the same time

Typical programming idiom:

...

L: read from a part of the data structure

do some work on the results

try to change the data structure

if interference is detected go to L

...

Non-blocking concurrency

Stacks, queues, skip lists, hash tables, etc.

Used in practice: e.g., java.util.concurrent

Complicated and hard to get right

Formal verification: Safety properties [Yahav+ 2003, Calcagno+ 2007, Amit+ 2007, Manevich+ 2008, Vafeiadis 2009]

Termination

?

Non-blocking concurrency: Treiber's stack

Top

42 13 1 4 NULL6

42 13

12

void push(data_t v) { Node *t, *x; x = new Node(); x->val = v; do { t = Top; x->next = t; } while(!CAS(&Top,t,x));}

data_t pop() { Node *t, *x; do { t = Top; if (t == NULL) return EMPTY; x = t->next; } while(!CAS(&Top,t,x)); return t->val;}

struct Node { Node *next; data_t val;} *Top;

Treiber's non-blocking stack: termination

void push(data_t v) { Node *t, *x; x = new Node(); x->val = v; do { t = Top; x->next = t; } while(!CAS(&Top,t,x));}

data_t pop() { Node *t, *x; do { t = Top; if (t == NULL) return EMPTY; x = t->next; } while(!CAS(&Top,t,x)); return t->val;}

struct Node { Node *next; data_t val;} *Top;

push or pop may not terminate if other threads continually modify Top

However: some operation will always terminate

This talk: logic & tool for proving lock-freedom

lock-freedom

From lock-freedom to termination

Lock-freedom of Treiber's stack

Push or Id

Shared stateRely/guarantee + separation logic for safety [Vafeiadis-Parkinson 2007]

void push(data_t v) { Node *t, *x; x = new Node(); x->val = v; do { t = Top; x->next = t; } while(!CAS(&Top,t,x));}

data_t pop() { Node *t, *x; do { t = Top; if (t == NULL) return EMPTY; x = t->next; } while(!CAS(&Top,t,x)); return t->val;}

struct Node { Node *next; data_t val;} *Top;

Pop or Id

Lock-freedom of Treiber's stack

Push or Id

void push(data_t v) { Node *t, *x; x = new Node(); x->val = v; do { t = Top; x->next = t; } while(!CAS(&Top,t,x));}

data_t pop() { Node *t, *x; do { t = Top; if (t == NULL) return EMPTY; x = t->next; } while(!CAS(&Top,t,x)); return t->val;}

struct Node { Node *next; data_t val;} *Top;

Pop or Id

Lock-freedom of Treiber's stack

The do loops terminate if no-one else executes Push or Pop infinitely often

No-one executes Push or Pop infinitely oftenHence, push and pop terminate

Push or Id

data_t pop() { Node *t, *x; do { t = Top; if (t == NULL) return EMPTY; x = t->next; } while(!CAS(&Top,t,x)); return t->val;}

void push(data_t v) { Node *t, *x; x = new Node(); x->val = v; do { t = Top; x->next = t; } while(!CAS(&Top,t,x));}

struct Node { Node *next; data_t val;} *Top;

Pop or Id

Layered proof

“I execute only Push, Pop, or Id”

“I don’t execute Push or Pop infinitely often”

“I don’t execute Push or Pop infinitely often”

“I terminate” “I terminate”

“I execute only Push, Pop, or Id”

Layered proofFormalised in a logic for liveness and heaps

Guarantees of the form

Run the safety checker:

Iteratively eliminate actions:

Proof search strategy

Proof valid for an arbitrary number of threads

Case studies

Treiber's stack [Treiber 1986]

HSY stack [Hendler+ 2004]

Non-blocking queue [Michael, Scott 1996]

Linked list [Michael 2002]

RDCSS [Harris+ 2002]

Conclusion

Automatic method with proofs reflecting algorithm structure

Hope the general approach can be reused

Lock-based lock-free algorithms require more complex environment assumptions

Recommended