150 likes | 262 Views
Memory Model Safety of Programs. Sebastian Burckhardt Madanlal Musuvathi Microsoft Research EC^2, July 7, 2008. Motivation: Memory Model Vulnerabilities. Programmers do not always follow strict locking discipline in performance-critical code
E N D
Memory Model Safety of Programs Sebastian BurckhardtMadanlal Musuvathi Microsoft Research EC^2, July 7, 2008
Motivation: Memory Model Vulnerabilities • Programmers do not always follow strict locking discipline in performance-critical code • Ad-hoc synchronization with normal loads and stores or interlocked operations is faster • Such code can break on relaxed memory models • Most multicore machines are not sequentially consistent • Both compilers and actual hardware can contribute to effect(we focus on hardware effects here) • Vulnerabilities are hard to find, reproduce, and analyze • May require specific hardware configuration and schedule
C# Example(found in production-level code) volatile boolisIdling; volatile boolhasWork; //Consumer thread void BlockOnIdle(){ lock (condVariable){ isIdling = true; if (!hasWork) Monitor.Wait(condVariable); isIdling = false; } } //Producer thread void NotifyPotentialWork(){ hasWork = true; if (isIdling) lock (condVariable) { Monitor.Pulse(condVariable); } }
Example: Store Buffer Vulnerability volatile int ii = 0; volatile int hw = 0; Consumer Producer Store ii, 1 Store ii, 1 Load hw, 0 Store hw, 1 Load ii, 1 0 Key pieces of code on previous slide: On x86, hardware may perform store late Bug: Producer thread does not notice waiting Consumer, does not send signal
Abstract View of Memory Models Given a program P, a memory model Y defines the subset TP,Y T of traces corresponding to some (partial or complete) execution of P on Y. TP, SC TP, Y T SC (sequential consistency) Is strongest memory model More executions may be possible on a relaxed memory model Y 5
Memory Model Safety Observation: Programmer writes code for SC • Resorts to {fences, volatiles, interlocked operations} to maintain SC behavior where needed • If program P exhibits non-SC behavior, it is most likely a bug Definition: A program P is Y-safe if TP,SC= TP,Y
Goal & Position Goal: Find efficient methods to verify / falsify memory model safety of programs. Position: Memory models should be formulated in a manner that facilitates this goal. It helps if a memory model Y … • … guarantees that data-race-free programs are Y-safe (but what about racy ones?) • … guarantees borderline executions (to be defined next).
Borderline Executions TP,SC TP,Y • Successor traces are traces with one more instruction. Def.: A borderline execution for P,Y is an execution in TP,SC with a successor in TP,Y- TP,SC
Example: TSO Borderline Execution TP, SC 1.1 Store ii, 1 2.1 Store hw, 1 TP, TSO 1.2 Load hw, 0 1.1 Store ii, 1 2.1 Store hw, 1 1.2 Load hw, 0 2.2 Load ii, 1 1.1 Store ii, 1 2.1 Store hw, 1 1.2 Load hw, 0 2.2 Load ii, 0 • Successor traces are traces with one more instruction.
Borderline Executions TP,SC TP,Y Def.: A borderline execution for P,Y is an execution in TP,SC with a successor in TP,Y- TP,SC Def.: A memory model Y guarantees borderline executions if the following property is true:A program P is Y-safe if and only if it has no borderline executions.
Borderline Executions We can verify / falsify this as a safety property of sequentially consistent executions! TP,SC TP,Y Def.: A borderline execution for P,Y is an execution in TP,SC with a successor in TP,Y- TP,SC Def.: A memory model Y guarantees borderline executions if the following property is true:A program P is Y-safe if and only if it has no borderline executions.
When does a Memory ModelGuarantee Borderline Executions? TP,Y TP,SC Simplest case: If each trace TP,Y has a predecessor in TP,Y , we can use simple induction (because empty trace is in TP,SC ). This is true for TSO, and we show in [CAV08] paper how to exploit this to build a borderline monitor.
How May a Memory Model Fail toGuarantee Borderline Executions? // Thread 1 // Thread 2 if (y = 1) if (x = 1) x = 1; y = 1; Load y, 1 Load x, 1 Store x, 1 Store y, 1 Sometimes, traces have no predecessors(i.e. we can not take away any one instruction).Example program: some memory models may allow this “circular” trace:
Conclusions / Future Work • With increasing use of multicores and little programmer regard for race-freedom, we expect more programs to exhibit failures caused by the memory model. • Borderline executions provide a practical way to verify / falsify memory model safety for a general class of memory models • Future work: how to deal with • Memory models without borderline executions • Memory models defined by compiler optimizations