Upload
belinda-goodwin
View
219
Download
2
Tags:
Embed Size (px)
Citation preview
1
Peng Liu and Charles Zhang
Prism Research Group
Department of Computer Science and Engineering
Hong Kong University of Science and Technology
Axis: Automatically Fixing Atomicity Violations
through Solving Control Constraints
2
Motivation
An Atomicity Violation (AV) in StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 1
3
Motivation
An Atomicity Violation (AV) in StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 1
4
Motivation
An Atomicity Violation (AV) in StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 1
5
Motivation
An Atomicity Violation (AV) in StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 1
6
Motivation
An Atomicity Violation (AV) in StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
run(){
s2.delete(0, s2.length()); }
Thread 1 Thread 2
7
Motivation
An Atomicity Violation (AV) in JDK StringBuffer.The accesses, assumed to be atomic, are interleaved non-serializably by a remote access.
run(){ // s1.append(s2): synchronized(s1) { a int len = s2.length();
b s2.getChars(0, len, s1…); }}
run(){
r s2.delete(0, s2.length()); }
Thread 1 Thread 2
8
Motivation
Common approach of Fixing the Atomicity ViolationSynchronize the atomicity sequence (from a to b) and the remote access (r) with locks.
run(){ // s1.append(s2): synchronized(s1) { + lockM.lock(); a int len = s2.length();
b s2.getChars(0, len, s1…); + lockM.unlock(); }}
run(){
+ lockM.lock(); r s2.delete(0, s2.length()); + lockM.unlock();
}
Thread 1 Thread 2
9
Motivation
Problems with Fixing the Violations
Sacrifice the concurrency!
IntroduceNew deadlocks!
10
Motivation
Problems with Fixing the Violations
Sacrifice the concurrency!
IntroduceNew deadlocks!
11
Motivation
Introduce New DeadlocksAV (a,b,r) and the original lock oL protecting some irrelevant vars.
Thread 1 Thread 2
a
oL.lock();…oL.unlock();
b
oL.lock();
...
r
...
oL.unlock();
12
Motivation
Introduce New DeadlocksAV (a,b,r) and the original lock oL protecting some irrelevant vars.
Thread 1 Thread 2
a
oL.lock();…oL.unlock();
b
oL.lock();
...
r
...
oL.unlock();
13
Motivation
Introduce New DeadlocksAV (a,b,r) and the original lock oL protecting some irrelevant vars.
Thread 1 Thread 2
a
oL.lock();…oL.unlock();
b
oL.lock();
...
r
...
oL.unlock();
14
Motivation
Introduce New DeadlocksAV (a,b,r) and the original lock oL protecting some irrelevant vars.
Thread 1 Thread 2
a
oL.lock();…oL.unlock();
b
oL.lock();
...
r
...
oL.unlock();
+ L.lock();
+ L.unlock();
+ L.lock();
+ L.unlock();
15
Motivation
Introduce New DeadlocksAV (a,b,r) and the original lock oL protecting some irrelevant vars.
Thread 1 Thread 2
a
oL.lock();…oL.unlock();
b
oL.lock();
...
r
...
oL.unlock();
+ L.lock();
+ L.unlock();
+ L.lock();
+ L.unlock();
16
Motivation
Problems with Fixing the Violations
Sacrifice the concurrency!
IntroduceNew deadlocks!
17
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
18
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
19
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
20
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
21
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
22
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
a
b
Thread 2
r’
a’
…r…
b’
23
Motivation
Sacrifice the Concurrency GreatlyTwo overlapping Avs: (a,b,r) and (a’b,r’).
Thread 1 Thread 3
+L.lock();a
b+L.unlock();
Thread 2
+L.lock();
r’
+L.unlock();
+L.lock();a’
…r…
b’ +L.unlock();
24
Motivation
Our Guarantee
Sacrifice the concurrency
minimally!
IntroduceNew deadlocks?
No!
25
Motivation
Our Guarantee
Sacrifice the concurrency
minimally!
IntroduceNew deadlocks?
No!
26
Motivation
Our ApproachCode ToPetri Net
Buggy Code
ConstraintConstructor
ConstraintSolver
Petri NetTo Code
RepairedCode
27
Motivation
Our ApproachCode ToPetri Net
Buggy Code
ConstraintConstructor
ConstraintSolver
Petri NetTo Code
RepairedCode
Bug report:<6@func1, 8@func1, 14@func2><2@func3, 14@func3, 20@func4>
……
28
Motivation
Our ApproachCode ToPetri Net
Buggy Code
ConstraintConstructor
ConstraintSolver
Petri NetTo Code
RepairedCode
29
Motivation
Our Approach
• Constraints: no two pandas on the single-plank bridge simultaneously.
• Solver: control theory.
ConstraintConstructor
ConstraintSolver
30
Motivation
Rationale
• Performance– Loose constraints–Concurrency-preserving solver.
• Safety–Handle deadlocks with solver
ConstraintConstructor
ConstraintSolver
31
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
32
Code ToPetri Net
Abstract graphical and mathematical model.
• Places (circles)• Transitions (horizontal bars)• Arcs between them
33
Code ToPetri Net
Abstract graphical and mathematical model.
• Places (circles)• Transitions (horizontal bars)• Arcs between them
34
Code ToPetri Net
Abstract graphical and mathematical model.
• Places (circles)• Transitions (horizontal bars)• Arcs between them
35
Code ToPetri Net
Abstract graphical and mathematical model.
• Places (circles)• Transitions (horizontal bars)• Arcs between them
36
Code ToPetri Net
Abstract graphical and mathematical model.
• Places contain tokens• Transitions, when
triggered, move tokens• Arcs (the weights)
determine how many to move. 1 by default.
37
Code ToPetri Net
Abstract graphical and mathematical model.
• Places contain tokens• Transitions, when
triggered, move tokens• Arcs (the weights)
determine how many to move. 1 by default.
38
Code ToPetri Net
Abstract graphical and mathematical model.
• Places contain tokens• Transitions, when
triggered, move tokens• Arcs (the weights) instruct
how many to remove or give. 1 by default.
39
Code ToPetri Net
Abstract graphical and mathematical model.
• A transition can be triggered only if the input place contains enough tokens.
40
Code ToPetri Net
Statements -> places. Control flows-> transitions
I f (…)
Branch 1 Branch 2
Branch
41
Code ToPetri Net
Statements -> places. Control flows-> transitions
I f (…)
Branch 1 Branch 2
Branch
42
Code ToPetri Net
Statements -> places. Control flows-> transitions
I f (…)
Branch 1 Branch 2
Branch
43
Code ToPetri Net
Statements -> places. Control flows-> transitions
I f (…)
Branch 1 Branch 2
Branch
44
Code ToPetri Net
Statements -> places. Control flows-> transitions
I f (…)
Branch 1 Branch 2
Branch
45
Code ToPetri Net
Statements -> places. Control flows-> transitions
while(…)
S1
S2
Loop
46
Code ToPetri Net
Statements -> places. Control flows-> transitions
while(…)
S1
S2
Loop
47
Code ToPetri Net
Statements -> places. Control flows-> transitions
while(…)
S1
S2
Loop
48
Code ToPetri Net
Statements -> places. Start/Join/Control flows-> transitions
thread1.start( ) ;thread2.start( ) ;
Threading
S1;S2;
S3;S4;
Thread 1: Thread 2:
thread1. join() ;thread2. join() ;
49
Code ToPetri Net
Statements -> places. Start/Join/Control flows-> transitions
thread1.start( ) ;thread2.start( ) ;
Threading
S1;S2;
S3;S4;
Thread 1: Thread 2:
thread1. join() ;thread2. join() ;
50
Code ToPetri Net
Statements -> places. Start/Join/Control flows-> transitions
thread1.start( ) ;thread2.start( ) ;
Threading
S1;S2;
S3;S4;
Thread 1: Thread 2:
thread1. join() ;thread2. join() ;
51
Code ToPetri Net
Statements -> places. Lock/Unlock/Control flows-> transitions
Locking
Thread 1:
L . lock() ;S1;L .unlock() ;
Thread 2:
L . lock() ;S2;L .unlock() ;
52
Code ToPetri Net
Statements -> places. Lock/Unlock/Control flows-> transitions
Locking
Thread 1:
L . lock() ;S1;L .unlock() ;
Thread 2:
L . lock() ;S2;L .unlock() ;
53
Code ToPetri Net
Statements -> places. Lock/Unlock/Control flows-> transitions
Locking
Thread 1:
L . lock() ;S1;L .unlock() ;
Thread 2:
L . lock() ;S2;L .unlock() ;
54
Code ToPetri Net
Mathematical form.
T1 T2
P1 -1
P2 0
P3 0 1
D =
Structure Matrix
(initial) Token Distribution Vector
U0 =
P1 1
P2 0
P3 0
P1
T1 T2
P2 P3-1
1
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
55
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
56
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P7
P8
P9
T6
T7
P6
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
57
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P7
P8
P9
T6
T7
P6
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
58
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
59
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Code ToPetri Net
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
60
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
ConstraintConstructor
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
ConstraintConstructor
62
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
run(){
s2.delete(0, s2.length()); }
thread1.join(); thread2.join();
ConstraintConstructor
63
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
ConstraintConstructor
64
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
Inter-thread constraint:U(P3) + U(P7) <=1
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
65
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
thread1.join(); thread2.join();
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
66
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
Inter-thread constraint:U(P4) + U(P7) <=1
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
67
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
thread1.join(); thread2.join();
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
68
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
thread1.join(); thread2.join();
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
69
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
thread1.start(); thread2.start();
Thread 1
run(){ synchronized(s1) { int len = s2.length();
s2.getChars(0, len, s1…); }}
Thread 2
thread1.join(); thread2.join();
run(){
s2.delete(0, s2.length()); }
ConstraintConstructor
70
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Intra-thread constraint:thread-representing token stays in P3, or P4, but not both at any time.U(P3) + U(P4) <=1
ConstraintConstructor
71
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Inter-thread:U(P3) + U(P7) <=1U(P4) + U(P7) <=1Intra-thread:U(P3) + U(P4) <=1
Equivalent form:U(P3) + U(P4) + U(P7) <=1
ConstraintSolver
Supervision Based on Place Invariants (SBPI)Input: constraints, e.g., U(P3) + U(P4) + U(P7) <=1Output: augmentation to PN to satisfy the constraints.
Output augmentation:• New control places with tokens• Arcs connecting them to the original PN.• Mathematic form.
ConstraintSolver
Output augmentation in its math form:• New control places with tokens• Arcs connecting them to the original PN.
Output of our example:• New place M. M has one token (U0
M = 1 ).• Connecting to T2, T6, from T4, T7. DM =
T1 T2 T3 T4 T5 T6 T7
M 0 -1 0 1 0 -1 1
ConstraintSolver
Output augmentation in its math form:• New control places with tokens• Arcs connecting them to the original PN.
Output of our example:• New place M. M has one token (U0
M = 1 ).• Connecting to T2, T6, from T4, T7. DM =
T1 T2 T3 T4 T5 T6 T7
M 0 -1 0 1 0 -1 1
ConstraintSolver
Output:• New place M, with one token.• Connecting to T2, T6, from T4, T7.
M
75
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
ConstraintSolver
Wang’s deadlock avoidance (SBPI) [POPL’09]• Reuse.• Part program. Deadlocks introduced by our fix.
Petri NetTo Code
• Control place -> lock (static field).• Arc to (from) a transition -> locking operation at
the control flow (between a pair of statements).
Injected locking operations should not affect other control flows (sharing common statements).
M
78
P1T1
P2T2
P3
T3P4T4
P5
L
T5
P6
P7
P8
P9
T6
T7
Petri NetTo Code
Thread 1synchronized(s1) { +lockM.lock(); int len = s2.length(); s2.getChars(0, len, s1…); +lockM.unlock(); }
Thread 2
+lockM.lock();s2.delete(0, s2.length());+lockM.unlock();
Evaluation
Benchmarks:• OpenJMS, messaging service implementation.• Derby, Apache’s database system.• Jigsaw, W3C’s webserver platform. Violation detection: Pecan [ISSTA ‘11]Evaluated properties:• Performance of patched code• Safety
Evaluation
Benchmarks:• OpenJMS, messaging service implementation.• Derby, Apache’s database system.• Jigsaw, W3C’s webserver platform. Violation detection: Pecan [ISSTA ‘11]Evaluated properties:• Performance of patched code• Safety
Evaluation (performance)
Compared to the state of the art fixes,1. Axis-noDA is 7% faster2. Axis-DA is only 3% slower. (It has strong safety guarantee.)
OpenJMS Jigsaw Derby
Evaluation (safety)
1. No deadlocks are identified for Axis-DA.2. Frequent deadlocks for other fixes, including Axis-noDA and
AFix.
Patched program T=2 T=4 T=8 T=12
OpenJMS Axis-noDA 0 0 2 7
AFix 0 0 2 5
Jigsaw Axis-noDA 20 20 20 20
AFix 20 20 20 20
Derby Axis-noDA 0 0 0 11
AFix 0 0 0 7
Conclusion
• A formal violation-fixing approach with strong guarantees on • Performance. Sacrifice the concurrency minimally.• Safety. No deadlocks are introduced.
• Implementation & Evaluation• Compared to the state of the art,• Axis-noDA is 7% faster.• Axis-DA (with strong safety guarantee) is merely
3% slower.
Thank you!Q&A