840 likes | 1k Views
Axis: Automatically Fixing Atomicity Violations through Solving Control Constraints. Peng Liu and Charles Zhang. Motivation. An Atomicity Violation (AV) in StringBuffer . The accesses, assumed to be atomic, are interleaved non- serializably by a remote access. Thread 1.
E N D
Axis: Automatically Fixing Atomicity Violations through Solving Control Constraints Peng Liu and Charles Zhang
Motivation An Atomicity Violation (AV) in StringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 run(){ // s1.append(s2): synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } }
Motivation An Atomicity Violation (AV) in StringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 run(){ // s1.append(s2): synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } }
Motivation An Atomicity Violation (AV) in StringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 run(){ // s1.append(s2): synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } }
Motivation An Atomicity Violation (AV) in StringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 run(){ // s1.append(s2): synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } }
Motivation An Atomicity Violation (AV) in StringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 Thread 2 run(){ // s1.append(s2): synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } } run(){ s2.delete(0, s2.length()); }
Motivation An Atomicity Violation (AV) in JDKStringBuffer. The accesses, assumed to be atomic, are interleaved non-serializably by a remote access. Thread 1 Thread 2 run(){ // s1.append(s2): synchronized(s1){ aintlen = s2.length(); b s2.getChars(0, len, s1…); } } run(){ r s2.delete(0, s2.length()); }
Motivation Common approach of Fixing the Atomicity Violation Synchronize the atomicity sequence (from a to b) and the remote access (r) with locks. Thread 1 Thread 2 run(){ // s1.append(s2): synchronized(s1){ + lockM.lock(); aintlen = s2.length(); b s2.getChars(0, len, s1…); + lockM.unlock(); } } run(){ + lockM.lock(); r s2.delete(0, s2.length()); + lockM.unlock(); }
Motivation Problems with Fixing the Violations Sacrifice the concurrency! Introduce New deadlocks!
Motivation Problems with Fixing the Violations Sacrifice the concurrency! Introduce New deadlocks!
Motivation Introduce New Deadlocks AV (a,b,r) and the original lock oL protecting some irrelevant vars. Thread 1 Thread 2 oL.lock(); a oL.lock(); … oL.unlock(); b ... r ... oL.unlock();
Motivation Introduce New Deadlocks AV (a,b,r) and the original lock oL protecting some irrelevant vars. Thread 1 Thread 2 oL.lock(); a oL.lock(); … oL.unlock(); b ... r ... oL.unlock();
Motivation Introduce New Deadlocks AV (a,b,r) and the original lock oL protecting some irrelevant vars. Thread 1 Thread 2 oL.lock(); a oL.lock(); … oL.unlock(); b ... r ... oL.unlock();
Motivation Introduce New Deadlocks AV (a,b,r) and the original lock oL protecting some irrelevant vars. Thread 1 Thread 2 oL.lock(); + L.lock(); a oL.lock(); … oL.unlock(); b ... r ... + L.lock(); + L.unlock(); + L.unlock(); oL.unlock();
Motivation Introduce New Deadlocks AV (a,b,r) and the original lock oL protecting some irrelevant vars. Thread 1 Thread 2 oL.lock(); + L.lock(); a oL.lock(); … oL.unlock(); b ... r ... + L.lock(); + L.unlock(); + L.unlock(); oL.unlock();
Motivation Problems with Fixing the Violations Sacrifice the concurrency! Introduce New deadlocks!
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 a’ … r … b’ r’ a b
Motivation Sacrifice the Concurrency Greatly Two overlapping Avs: (a,b,r) and (a’b,r’). Thread 1 Thread 2 Thread 3 +L.lock(); a’ … r … b’ +L.unlock(); +L.lock(); r’ +L.unlock(); +L.lock(); a b +L.unlock();
Motivation Our Guarantee Sacrifice the concurrency minimally! Introduce New deadlocks? No!
Motivation Our Guarantee Sacrifice the concurrency minimally! Introduce New deadlocks? No!
Motivation Our Approach Buggy Code CodeTo Petri Net Constraint Constructor Constraint Solver Repaired Code Petri Net To Code
Motivation Our Approach Buggy Code CodeTo Petri Net Constraint Constructor Constraint Solver Repaired Code Petri Net To Code Bug report: <6@func1, 8@func1, 14@func2> <2@func3, 14@func3, 20@func4> ……
Motivation Our Approach Buggy Code CodeTo Petri Net Constraint Constructor Constraint Solver Repaired Code Petri Net To Code
Motivation Our Approach • Constraints: no two pandas on the single-plank bridge simultaneously. • Solver: control theory. Constraint Constructor Constraint Solver
Motivation Rationale • Performance • Loose constraints • Concurrency-preserving solver. • Safety • Handle deadlocks with solver Constraint Constructor Constraint Solver
CodeTo Petri Net thread1.start(); thread2.start(); Thread 1 Thread 2 run(){ s2.delete(0, s2.length()); } run(){ synchronized(s1){ intlen = s2.length(); s2.getChars(0, len, s1…); } } thread1.join(); thread2.join();
CodeTo Petri Net • Abstract graphical and mathematical model. • Places (circles) • Transitions (horizontal bars) • Arcs between them
CodeTo Petri Net • Abstract graphical and mathematical model. • Places (circles) • Transitions (horizontal bars) • Arcs between them
CodeTo Petri Net • Abstract graphical and mathematical model. • Places (circles) • Transitions (horizontal bars) • Arcs between them
CodeTo Petri Net • Abstract graphical and mathematical model. • Places (circles) • Transitions (horizontal bars) • Arcs between them
CodeTo Petri 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.
CodeTo Petri 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.
CodeTo Petri 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.
CodeTo Petri Net • Abstract graphical and mathematical model. • A transition can be triggered only if the input place contains enough tokens.
CodeTo Petri Net Statements -> places. Control flows-> transitions Branch If(…) Branch 1 Branch 2
CodeTo Petri Net Statements -> places. Control flows-> transitions Branch If(…) Branch 1 Branch 2
CodeTo Petri Net Statements -> places. Control flows-> transitions Branch If(…) Branch 1 Branch 2
CodeTo Petri Net Statements -> places. Control flows-> transitions Branch If(…) Branch 1 Branch 2
CodeTo Petri Net Statements -> places. Control flows-> transitions Branch If(…) Branch 1 Branch 2
CodeTo Petri Net Statements -> places. Control flows-> transitions Loop while(…) S1 S2
CodeTo Petri Net Statements -> places. Control flows-> transitions Loop while(…) S1 S2
CodeTo Petri Net Statements -> places. Control flows-> transitions Loop while(…) S1 S2
CodeTo Petri Net Statements -> places. Start/Join/Control flows-> transitions Threading thread1.start(); thread2.start(); Thread 1: Thread 2: S1; S2; S3; S4; thread1.join(); thread2.join();
CodeTo Petri Net Statements -> places. Start/Join/Control flows-> transitions Threading thread1.start(); thread2.start(); Thread 1: Thread 2: S1; S2; S3; S4; thread1.join(); thread2.join();
CodeTo Petri Net Statements -> places. Start/Join/Control flows-> transitions Threading thread1.start(); thread2.start(); Thread 1: Thread 2: S1; S2; S3; S4; thread1.join(); thread2.join();