Download presentation
Presentation is loading. Please wait.
Published byBelinda Goodwin Modified over 9 years ago
1
Peng Liu and Charles Zhang Prism Research Group Department of Computer Science and Engineering Hong Kong University of Science and Technology 1
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 2
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 3
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 4
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 5
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 6
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 7
8
Motivation Common approach of Fixing the Atomicity Violation Synchronize 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 8
9
Motivation Problems with Fixing the Violations 9
10
Motivation Problems with Fixing the Violations 10
11
Motivation Introduce New Deadlocks AV (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(); 11
12
Motivation Introduce New Deadlocks AV (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
13
Motivation Introduce New Deadlocks AV (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
14
Motivation Introduce New Deadlocks AV (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(); 14
15
Motivation Introduce New Deadlocks AV (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
16
Motivation Problems with Fixing the Violations 16
17
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 17
18
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 18
19
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 19
20
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 20
21
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 21
22
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 3 a b a b Thread 2 r’ a’ … r … b’ 22
23
Motivation Sacrifice the Concurrency Greatly Two 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(); 23
24
Motivation Our Guarantee 24
25
Motivation Our Guarantee 25
26
Motivation Our Approach 26
27
Motivation Our Approach Bug report: …… 27
28
Motivation Our Approach 28
29
Motivation Our Approach Constraints: no two pandas on the single-plank bridge simultaneously. Solver: control theory. 29
30
Motivation Rationale Performance – Loose constraints – Concurrency-preserving solver. Safety – Handle deadlocks with solver 30
31
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(); 31
32
Abstract graphical and mathematical model. Places (circles) Transitions (horizontal bars) Arcs between them 32
33
Abstract graphical and mathematical model. Places (circles) Transitions (horizontal bars) Arcs between them 33
34
Abstract graphical and mathematical model. Places (circles) Transitions (horizontal bars) Arcs between them 34
35
Abstract graphical and mathematical model. Places (circles) Transitions (horizontal bars) Arcs between them 35
36
Abstract graphical and mathematical model. Places contain tokens Transitions, when triggered, move tokens Arcs (the weights) determine how many to move. 1 by default. 36
37
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
38
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. 38
39
Abstract graphical and mathematical model. A transition can be triggered only if the input place contains enough tokens. 39
40
Statements -> places. Control flows-> transitions Branch 40
41
Statements -> places. Control flows-> transitions Branch 41
42
Statements -> places. Control flows-> transitions Branch 42
43
Statements -> places. Control flows-> transitions Branch 43
44
Statements -> places. Control flows-> transitions Branch 44
45
Statements -> places. Control flows-> transitions Loop 45
46
Statements -> places. Control flows-> transitions Loop 46
47
Statements -> places. Control flows-> transitions Loop 47
48
Statements -> places. Start/Join/Control flows-> transitions Threading 48
49
Statements -> places. Start/Join/Control flows-> transitions Threading 49
50
Statements -> places. Start/Join/Control flows-> transitions Threading 50
51
Statements -> places. Lock/Unlock/Control flows-> transitions Locking 51
52
Statements -> places. Lock/Unlock/Control flows-> transitions Locking 52
53
Statements -> places. Lock/Unlock/Control flows-> transitions Locking 53
54
Mathematical form. 54 T1T2 P1 P20 P301 D = Structure Matrix (initial) Token Distribution Vector U 0 = P11 P20 P30 P1 T1T2 P2 P3 1
55
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
56
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P7 P8 P9 T6 T7 P6
57
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P7 P8 P9 T6 T7 P6
58
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
59
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
60
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 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
61
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(); P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
62
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(); 62 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
63
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(); 63 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
64
64 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
65
65 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
66
66 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
67
67 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
68
68 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
69
69 P1 T1 P2 T2 P3 T3 P4 T4 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()); }
70
70 P1 T1 P2 T2 P3 T3 P4 T4 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
71
71 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7 Inter-thread: U(P3) + U(P7) <=1 U(P4) + U(P7) <=1 Intra-thread: U(P3) + U(P4) <=1 Equivalent form: U(P3) + U(P4) + U(P7) <=1
72
Supervision Based on Place Invariants (SBPI) Input: constraints, e.g., U(P3) + U(P4) + U(P7) <=1 Output: augmentation to PN to satisfy the constraints. Output augmentation: New control places with tokens Arcs connecting them to the original PN. Mathematic form.
73
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 (U 0 M = 1 ). Connecting to T2, T6, from T4, T7. D M = T1T2T3T4T5T6T7 M0010 1
74
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 (U 0 M = 1 ). Connecting to T2, T6, from T4, T7. D M = T1T2T3T4T5T6T7 M0010 1
75
Output: New place M, with one token. Connecting to T2, T6, from T4, T7. M 75 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7
76
Wang’s deadlock avoidance (SBPI) [POPL’09] Reuse. Part program. Deadlocks introduced by our fix.
77
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).
78
M 78 P1 T1 P2 T2 P3 T3 P4 T4 P5 L T5 P6 P7 P8 P9 T6 T7 Thread 1 synchronized(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();
79
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
80
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
81
Evaluation (performance) Compared to the state of the art fixes, 1.Axis-noDA is 7% faster 2.Axis-DA is only 3% slower. (It has strong safety guarantee.) OpenJMSJigsaw Derby
82
Evaluation (safety) 1.No deadlocks are identified for Axis-DA. 2.Frequent deadlocks for other fixes, including Axis-noDA and AFix. Patched programT=2T=4T=8T=12 OpenJMSAxis-noDA0027 AFix0025 JigsawAxis-noDA20 AFix20 DerbyAxis-noDA00011 AFix0007
83
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.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.