150 likes | 292 Vues
This course presents an in-depth exploration of atomicity within concurrent programming, focusing on the development of interfaces that ensure atomic operations are maintained consistently across threads. Participants will learn various techniques to assess thread compatibility, weak conflict serializability, and the implications of read/write operations in concurrent executions. Throughout the course, we will investigate scenarios demonstrating serial execution equivalency and develop algorithms for creating thread interfaces to manage complex interaction patterns effectively.
E N D
Interfaces for atomicity Vasu Singh SAV Course 2007
Programming language S ::= lx:=read(x) | x:=write(lx) | assume(lx) | assert(lx) | while(lx){S} | S;S | S[]S | LocalCmds • Let a program P be a concurrent execution of a set of threads. • lx:=read(x); • assume(lx>0); • ly:=read(y); • lx:=lx+ly; • x:=write(lx); 6. lx:=read(x); 7. assume(lx>0); 8. y:=write(2);
Definition of atomicity For every execution of the program, there exists an execution where the threads execute serially. Consider the execution: 1, 6, 2, 3, 7, 4, 8, 5. So, T1 reads x=6, y=1; writes x=7. T2 reads x=1, writes y=2. Does there exist an equivalent serial execution ? No. Initially, x=6, y=1; • lx:=read(x); • assume(lx>5); • ly:=read(y); • lx:=lx+ly; • x:=write(lx); 6. lx:=read(x); 7. assume(lx>5); 8. y:=write(2);
Something interesting to note… • If we ignore the read values in the threads (only look at the written values), then there is an equivalent serial execution for the given example • Idea: Can we weaken the notion of ‘atomicity’ to allow more programs to satisfy the property?
Conflict serializability • An equivalent notion of atomicity in databases: Given a sequence of data operations (read/write) by different transactions, does there exist a serial history that preserves order of conflicting operations? • Example: rd x, wr x, c, c => rd x, c, wr x, c
Why preserve order? • Preserving the order of conflicting operations ensures that values read from and written to the database are exactly the same (without even looking at the values) • Question 1:Do we need to keep the read values intact in a serial history? • Question 2:How do we guarantee that the written values remain the same?
Weak conflict serializability • For each transaction, remember the read set RS, the write set WS, and a set of predicates on the read set (assumptions), and a set of predicates on the write set (guarantees). • Instead of defining conflicts just using RS and WS, use more information (assumptions and guarantees) to decide conflicting operations. • Let us motivate this by an example…
In our example… • Thread 1: read(x); read(y); write(x); • Assumptions: x’=x; y’=y; • Guarantees: x>5 implies x’ > 5; • x<=5 implies x’=x; • Thread 2: read(x); write(y); • Assumptions: x>5 x’>5; • Guarantee: y’ = 2; • lx:=read(x); • assume(lx>5); • ly:=read(y); • lx:=lx+ly; • x:=write(lx); 6. lx:=read(x); 7. assume(lx>5); 8. y:=write(2);
Developing interfaces • Interface for a thread: Sequence of read/write operations on global variables, along with assumptions on RS and guarantees on WS. • To check whether two threads are atomic with each other, just check for compatibility of their interfaces.
Defining weak conflicts • write(x) conflicts with write(x) • read(x) conflicts with previous write(x) • write(x) conflicts with previous read(x) if guarantee(x) does not imply assumption(x) • Thus, weak conflict serializability preserves the order of writes, and writes followed by reads, but may reorder reads followed by writes
Conflict serializable? • lx:=read(x); • assume(lx>0); • ly:=read(y); • lx:=lx+ly; • x:=write(lx); Cycle formed! RS: x RS: x RS: y WS: y 6. lx:=read(x); 7. assume(lx>0); 8. y:=write(2); WS: x
Weakened Conflict serializable? • lx:=read(x); • assume(lx>0); • ly:=read(y); • lx:=lx+ly; • x:=write(lx); Assumption: x>5 x’>5 Guarantee: y’=2 RS: x RS: x RS: y WS: y 6. lx:=read(x); 7. assume(lx>0); 8. y:=write(2); WS: x Assumption: x’=x; y’=y Guarantee: x>5 x’>5
Algorithm • Create the interfaces for the two threads. • Consider all possible interleavings of the interfaces. We gain because the number of interleavings of the interfaces is expected to be substantially smaller than the interleavings of the original program • Check whether every interleaving gives an acyclic weak conflict graph.
Pure loops • while(true){ if (x=0) { y:=0; break;} } expressed as while(true){ lx:=read(x); assume lx=0; y:=write(0); break; [] assume lx!=0; }
Pending and future work • Create interfaces for loops • Develop a way to generate interfaces automatically (future work)