150 likes | 280 Views
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
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)