300 likes | 405 Views
This paper presents a novel approach to creating highly concurrent versions of data structures from their sequential implementations through automatic fine-grained locking. By leveraging the Domination Locking Protocol, the method guarantees correctness, atomicity, deadlock freedom, and a high level of parallelism. It introduces early release mechanisms and distinguishes between exposed and hidden objects, enabling efficient synchronization. The approach is evaluated through various data structures, including balanced search trees, demonstrating its scalability and effectiveness in enhancing concurrency without extensive manual intervention.
E N D
Automatic Fine-Grained Synchronizationvia Domination Locking 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
Creating Highly Concurrent Data-Structures • Given a sequential implementation of a data-structure • Automatically create a correct highly concurrent version of this data-structure
Creating Highly Concurrent Data-Structures via Fine-Grained Locking • Automatically add locks to guarantee: • Correctness • Atomicity • Deadlock freedom • High level of parallelism • Fine-grained locks, lock for each object • A lock is only held while necessary
Creating Highly Concurrent Data-Structures via Fine-Grained Locking • Automatically add locks to guarantee: • Correctness • Atomicity • Deadlock freedom • High level of parallelism • Fine-grained locks, lock for each object • A lock is only held while necessary list n2 n1 n3 n4 early release
Example: remove from a balanced search-tree (Treap) When should I acquire and release each lock? Under what conditions?
Locking Protocol • Enforce a locking protocol in the given code • What locking protocol do we need to enforce? • How to enforce this protocol in the given code?
What locking protocol? • Two Phase Locking • Does not allow early release • Tree/DAG locking • Assume that the objects graph is static • Dynamic versions of Tree/DAG locking
Our Approach: The Domination Locking Protocol • Works for any shape • Allows early release
Two types of objects • Distinguishes between exposed and hidden objects • Exposed objects • “roots” of data structures • may be pointed by transaction arguments • Hidden objects • may not be pointed by transaction arguments • may be reachable via exposed objects List ... void insert(List l, int k) {…} hidden hidden hidden exposed
Restricted Semantics • Leverages the restricted semantics of software modules • thread can access n3 only after n1 & n2 List n2 n1 n3 n4 exposed hidden hidden hidden
Domination Locking transaction t can access object only when holding its lock an hidden object u can be acquired by t only if every path between an exposed object to u includes an object which is locked by t DS a1 a2 a4 a3 a7 a5 a6
assume ≤ be a total order of objects • t can acquire an exposed object u, only if • t has never acquired an exposed object v ≤ u • t has never released a lock DSA a1 ... DSB b1 ...
Concurrent Correctness from Sequential Conditions If every sequential execution satisfies DL and is able to terminate • concurrent operations are conflict-serializable and deadlock-free (Intuition similar to Rinetzky et. al POPL’10)
Automatic Locking • A method to enforce DL when shape== forest • add locking by relying on the restricted shape • without understanding the details of the given code
Forest-Based Data-Structure • In every sequential execution, shape is a forest at the beginning and end of transactions
Forest-Based Data-Structure • In every sequential execution, shape is a forest at the beginning and end of transactions • Example: ListA forest violation a1 a2 a3 a4 move a3 from ListA to ListB ListB b1 b2 b3 b4
Forest-Based Data Structure • Consistent objects • exposed object has no predecessors • hidden object has 0 or 1 predecessors (unshared) • A data-structure is forest-based if • In every sequential execution, all object are consistent at the beginning and end of transactions
Reference counters We add to two reference counters to objects • Stack reference counter • counts number of incoming pointers from private memory (stack variables) • Heap reference counter • counts number of incoming pointers from heap objects
Reference counters s=1 h=0 s=0 h=1 s=0 h=0 s=0 h=2 s=1 h=1 y x
Locking • Acquire object u when • stack counter of u becomes positive • Release object u when • stack counter of u becomes 0 • u is consistent
s=1 h=0 s=0 h=1 s=0 h=0 s=1 h=1 s=0 h=1 x y
s=1 h=0 s=0 h=1 s=0 h=0 s=1 h=2 s=0 h=1 x y
s=1 h=0 s=0 h=1 s=0 h=0 s=0 h=2 s=1 h=1 y x
Locking Arguments void Move(List x, List y) { … void Move(List x, List y) { { if( address(x) <= address(y) ) { acquire(x); acquire(y); } else { acquire(y); acquire(x); } … • Acquire *x and *y without leading to a deadlock • Define a unique identifier for each object • e.g. use memory addresses • Acquire according the order of identifiers
Summary • New Locking Protocol – Domination Locking • Applies to any shape • Allows early release • Automatic realization for forest-based data-structures • Preliminary Evaluation • Automatic fine-grained locking for red-black tree and others • Scales similarly to hand crafted locking