150 likes | 271 Vues
This paper discusses the vulnerabilities associated with memory models in multicore programming. It highlights how programmers often neglect strict locking protocols, opting for performance-centric ad-hoc synchronization, leading to potential failures on relaxed memory models. The authors emphasize that both compilers and hardware play critical roles in these issues, making vulnerabilities difficult to detect and reproduce. The concept of borderline executions is introduced as a mechanism to verify memory model safety, aiming to pave the way for efficient methods to assess and improve program reliability in a multicore environment.
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