320 likes | 412 Views
Automatic Fine-Grain Locking using Shape Properties. Guy Golan Gueta Tel-Aviv University Nathan Bronson Stanford University Alex Aiken Stanford University G. Ramalingam Microsoft Research Mooly Sagiv Tel-Aviv University Eran Yahav Technion. Concurrent Data Structures.
E N D
Automatic Fine-Grain Locking using Shape Properties Guy Golan Gueta Tel-Aviv University Nathan Bronson Stanford University Alex Aiken Stanford University G. Ramalingam Microsoft Research Mooly Sagiv Tel-Aviv University Eran Yahav Technion
Concurrent Data Structures • Widely used in many software systems • Coarse-grain locking • e.g.: a single lock • easy to implement and understand • often not efficient enough • limited concurrency • Fine-grain locking • high-degree of concurrency • extremely hard to implement and understand
Challenge: Automatic Fine-Grain Locking • Automatically add fine-grain locking to sequential code • recursive data structures (e.g. trees, lists) Sequential Code Concurrent Code intGetMax(Node p) { Node c; c = p.right; while (c!=null) { p=c; c=c.right; } int t = p.value; return t; } intGetMax(Node p) { Node c; lock(p); c = p.right; lock(c); while (c!=null) { unlock(p); p=c; c=c.right; if(c!=null) lock(c); } int t = p.value; unlock(p); return t; }
Fine-Grain Locking • Each heap object has its own lock Data Structure n1 n2 n4 n3 n5 n6 … … …
Fine-Grain Locking • Each heap object has its own lock • A lock is only held while necessary Data Structure Thread T’ Thread T n1 early unlock n2 n4 n3 n5 n6 … … …
Adding fine-grain locking is hard • Adding fine-grain locking to pointer based data structures is hard • Need to understand complicated properties • Hard in sequential programs • Harder in the presence of concurrency
This paper provides two ideas • Locking protocol for fine-grain locking, Domination Locking • Conditions that guarantees atomicity and deadlock-freedom • Can be enforced by programmers • Requires only sequential reasoning • Generalization of several known locking protocols • Examples: hand-over-hand locking, dynamic DAG locking • Automatic method to enforce the protocol • Assumes that the heap is a forest at the beginning of each operation • Can be checked dynamically • No use of shape analysis • Static + Dynamic: adds conditional lock and unlock statements
Restricted Objects Access • Leverage the restricted way well-typed programs access heap objects • Cannot access n3 without accessing n2 Local Stack Data Structure n1 X n2 n4 n3 n5 n6 … … …
Two Types of Objects • Distinguishes between two types of objects: • Exposed objects: “roots” of data structures • Hidden objects: reachable only via exposed objects Local Stack exposed Data Structure n1 X hidden hidden n2 n4 hidden hidden hidden n3 n5 n6 … … …
Domination Thread T dominates object u: Paths from exposed objects to u include an object locked by T T dominates h4, h5 exposed exposed T does not dominate h3 e1 e2 Thread T h4 h3 h5
Domination Locking Protocol Thread can access object, only when holding its lock exposed e1 h2 h3 Thread T
Domination Locking Protocol Thread can access object, only when holding its lock Thread can lock hidden object u, only when it dominates u Early unlock is legal Cycle exposed e1 h2 h3 Thread T
Domination Locking Protocol Thread can access object, only when holding its lock Thread can lock hidden object u, only when it dominates u Early unlock is legal Cycle exposed e1 h2 h3 h4 Thread T Heap graph can be dynamically changed
Domination Locking Protocol Thread can access object, only when holding its lock Thread can lock hidden object u, only when it dominates u For exposed objects, use variant of two-phase locking that avoids deadlocks Early unlock is legal Cycle exposed e1 h2 h3 h4 Thread T Heap graph can be dynamically changed
Domination Locking Protocol Thread can access object, only when holding its lock Thread can lock hidden object u, only when it dominates u For exposed objects, use variant of two-phase locking that avoids deadlocks Several exposed objects exposed e1 h2 h3 h4 exposed e5
Concurrent Correctness from Sequential Conditions • If every sequential execution satisfies the protocol and is able to terminate → all concurrent executions are linearizable and are able to terminate • Simplifies reasoning • But automatic enforcement in real code with complicated data structures is still not obvious
Sequential code boolean remove(Nd par, int key) { Nd n = null; n = par.right; while (n != null && key != n.key) { par = n; n = (key < n.key) ? n.left : n.right; } if (n == null) return false; NdnL = n.left; NdnR = n.right; while (true) { NdbestChild = (nL == null || (nR != null && nR.prio > nL.prio)) ? nR : nL; if (n == par.left) par.left = bestChild; else par.right = bestChild; if (bestChild == null) break; if (bestChild == nL) { // ROTATION n.left = nL.right; nL.right = n; nL = n.left; } else {// ROTATION n.right = nR.left; nR.left = n; nR = n.right; } par = bestChild; } return true; } ?
Dynamic Forest Data Structure • In every sequential execution, shape is a forest at the beginning and end of operations • Example: ListA e1 h2 h3 h4 ListB e5 h6 h7 h8
Dynamic Forest Data Structure • In every sequential execution, shape is a forest at the beginning and end of operations • Example: ListA Forest violation e1 h2 h3 h4 Move h3 from ListA to ListB ListB e5 h6 h7 h8
How does forestness help? • Guarantees unique ownership at the beginning of every operation • Helps identifying where to safely release locks
Automatic Method • Adds code that collects runtime information • Adds code that uses this information for locking and unlocking
Runtime Information Two reference counters to every heap object • Stack reference counter • counts number of incoming pointers from local stack (private memory) • Heap reference counter • counts number of incoming pointers from heap objects
Runtime Information h4 Local Stack Heap Ref = 0 X Y Stack Ref = 1 exposed Heap Ref = 0 Heap Ref = 2 Heap Ref = 1 Stack Ref = 0 Stack Ref = 0 Stack Ref = 1 e1 h2 h3
Locking and Unlocking Locking\Unlocking by using the reference counters • Lock object when • its stack counter becomes positive • Unlock object when • its stack counter becomes 0 • not part of a forest violation (according the heap counter)
Multiple Trees Code that locks pointedobjects in a fixed order void Move(Tree X, Tree Y) { … void Move(Tree X, Tree Y) { { if( address(X) <= address(Y) ) { lock(X); lock(Y); } else { lock(Y); lock(X); } …
Performance Evaluation • Add fine grain locking to several data structures • 2 balanced search trees (Treap, Red-Black Tree) • Self Adjusting Heap (Skew Heap) • 2 specialized data structures (Apriori, and Barnes-Hut) • Runtime experiments show good scalability • No optimization were used (a lot of room for optimizations)
Automatic FGL vs. Manual FGL • Treap
Automatic FGL vs. Manual FGL • Apriori
Summary • A new fine-grain locking protocol for dynamic heaps – Domination Locking • Automatic realization for dynamic forests • Adds fine-grain locking for red-black trees and others • Preliminary Performance Evaluation • scales similarly to hand crafted locking