Transcript slides

Automatic Fine-Grained Synchronization
via Domination Locking
Guy Golan-Gueta
Nathan Bronson
Alex Aiken
G. Ramalingam
Mooly Sagiv
Eran Yahav
Tel-Aviv University
Stanford University
Stanford University
Microsoft Research
Tel-Aviv University
Technion
Creating Highly Concurrent
Data-Structures
• Given a sequential implementation of a datastructure
• 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
n1
early release
n2
n3
n4
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
void insert(List l, int k) {…}
List
...
exposed
hidden
hidden
hidden
Restricted Semantics
• Leverages the restricted semantics of software
modules
– thread can access n3 only after n1 & n2
List
n1
exposed
n2
n3
n4
hidden
hidden
hidden
Domination Locking
1. transaction t can access object only when holding its lock
2. 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
a3
a4
a7
a5
a6
assume ≤ be a total order of objects
3. 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
Example: remove from a balanced search-tree (Treap)
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
a1
forest violation
a2
a3
move a3 from ListA to ListB
ListB
b1
a4
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
y
s=0 h=0
s=0 h=1
s=0 h=2
s=1 h=1
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
y
s=0 h=0
s=0 h=1
s=1 h=1
x
s=0 h=1
s=1 h=0
y
s=0 h=0
s=0 h=1
s=1 h=2
x
s=0 h=1
s=1 h=0
y
s=0 h=0
s=0 h=1
s=0 h=2
s=1 h=1
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
RB tree (top-down implementation)
Single
Eager
Throughput (ops/msec)
600
500
400
300
200
100
0
1
2
4
8
Threads
16
32
64
Treap
Single
Hand-Crafted
Eager
1800
Throughput (ops/msec)
1600
1400
1200
1000
800
600
400
200
0
1
2
4
8
Threads
16
32
64
Apriori
Single
Original (fine-grained)
Eager
120%
Normalized Time
100%
80%
60%
40%
20%
0%
1
2
4
Threads
8
Summary
• New Locking Protocol – Domination Locking
– Applies to any shape
– Allows early release
• Automatic realization for forest-based datastructures
• Preliminary Evaluation
– Automatic fine-grained locking for red-black tree
and others
– Scales similarly to hand crafted locking
Thank You