A taxonomy of race. D. P. Helmbold, C. E. McDowell. September 28, University of California, Santa Cruz. Santa Cruz, CA

Similar documents
A taxonomy of race. D. P. Helmbold, C. E. McDowell. September 28, University of California, Santa Cruz. Santa Cruz, CA

1.1 Related work Our taxonomy aims at providing a terminology of replay debugger characteristics. The need for a debugging terminology has been formal

RACE CONDITION DETECTION FOR DEBUGGING SHARED-MEMORY PARALLEL PROGRAMS

The Compositional C++ Language. Denition. Abstract. This document gives a concise denition of the syntax and semantics

C. E. McDowell August 25, Baskin Center for. University of California, Santa Cruz. Santa Cruz, CA USA. abstract

SAMOS: an Active Object{Oriented Database System. Stella Gatziu, Klaus R. Dittrich. Database Technology Research Group

Consistent Logical Checkpointing. Nitin H. Vaidya. Texas A&M University. Phone: Fax:

2 Data Reduction Techniques The granularity of reducible information is one of the main criteria for classifying the reduction techniques. While the t

Foundations of the C++ Concurrency Memory Model

to automatically generate parallel code for many applications that periodically update shared data structures using commuting operations and/or manipu

On Checkpoint Latency. Nitin H. Vaidya. In the past, a large number of researchers have analyzed. the checkpointing and rollback recovery scheme

Algebraic Properties of CSP Model Operators? Y.C. Law and J.H.M. Lee. The Chinese University of Hong Kong.

David P. Helmbold. Charles E. McDowell. University of California at Santa Cruz. abstract

Joint Entity Resolution

UNIVERSITY OF CALIFORNIA. Irvine. Using Static Concurrency Analysis to. Understand the Dynamic Behavior of. Concurrent Programs

APPLICATION OF THE FUZZY MIN-MAX NEURAL NETWORK CLASSIFIER TO PROBLEMS WITH CONTINUOUS AND DISCRETE ATTRIBUTES

second_language research_teaching sla vivian_cook language_department idl

C++ Memory Model. Martin Kempf December 26, Abstract. 1. Introduction What is a Memory Model

Incompatibility Dimensions and Integration of Atomic Commit Protocols

Steering. Stream. User Interface. Stream. Manager. Interaction Managers. Snapshot. Stream

Solve the Data Flow Problem

CS510 Advanced Topics in Concurrency. Jonathan Walpole

under Timing Constraints David Filo David Ku Claudionor N. Coelho, Jr. Giovanni De Micheli

Handout 9: Imperative Programs and State

director executor user program user program signal, breakpoint function call communication channel client library directing server

Memory model for multithreaded C++: August 2005 status update

Section 8. The Basic Step Algorithm

r[2] = M[x]; M[x] = r[2]; r[2] = M[x]; M[x] = r[2];

Enhancing Integrated Layer Processing using Common Case. Anticipation and Data Dependence Analysis. Extended Abstract

Transport protocols are of practical. login, le transfer, and remote procedure. calls. will operate on and therefore are generally

Software Component Relationships. Stephen H. Edwards. Department of Computer Science. Virginia Polytechnic Institute and State University

The Simplex Algorithm with a New. Primal and Dual Pivot Rule. Hsin-Der CHEN 3, Panos M. PARDALOS 3 and Michael A. SAUNDERS y. June 14, 1993.

Parallel Rewriting of Graphs through the. Pullback Approach. Michel Bauderon 1. Laboratoire Bordelais de Recherche en Informatique

Implementing Sequential Consistency In Cache-Based Systems

Network. Department of Statistics. University of California, Berkeley. January, Abstract

A Dag-Based Algorithm for Distributed Mutual Exclusion. Kansas State University. Manhattan, Kansas maintains [18]. algorithms [11].

OS06: Monitors in Java

An Evaluation of Information Retrieval Accuracy. with Simulated OCR Output. K. Taghva z, and J. Borsack z. University of Massachusetts, Amherst

On Object Orientation as a Paradigm for General Purpose. Distributed Operating Systems

(Preliminary Version 2 ) Jai-Hoon Kim Nitin H. Vaidya. Department of Computer Science. Texas A&M University. College Station, TX

perspective, logic programs do have a notion of control ow, and the in terms of the central control ow the program embodies.

size, runs an existing induction algorithm on the rst subset to obtain a rst set of rules, and then processes each of the remaining data subsets at a


Persistent Oberon Language Specification

CHAPTER 5 GENERATING TEST SCENARIOS AND TEST CASES FROM AN EVENT-FLOW MODEL

Server 1 Server 2 CPU. mem I/O. allocate rec n read elem. n*47.0. n*20.0. select. n*1.0. write elem. n*26.5 send. n*

Data-Race Detection in Transactions- Everywhere Parallel Programming

Subject: Scheduling Region Questions and Problems of new SystemVerilog commands

A Unified Formalization of Four Shared-Memory Models

Acknowledgments 2

control edge synchronization edge MGOTO COEND

An Introduction to OpenMP

Curriculum 2013 Knowledge Units Pertaining to PDC

CalFuzzer: An Extensible Active Testing Framework for Concurrent Programs Pallavi Joshi 1, Mayur Naik 2, Chang-Seo Park 1, and Koushik Sen 1

Abstract. Programs written in languages of the Oberon family usually. contain runtime tests on the dynamic type of variables.

Availability of Coding Based Replication Schemes. Gagan Agrawal. University of Maryland. College Park, MD 20742

Algorithmic "imperative" language

Written Presentation: JoCaml, a Language for Concurrent Distributed and Mobile Programming

Adaptive Methods for Distributed Video Presentation. Oregon Graduate Institute of Science and Technology. fcrispin, scen, walpole,

\Symbolic Debugging of. Charles E. McDowell. April University of California at Santa Cruz. Santa Cruz, CA abstract

Parametric and provisioning approaches are again obviously useful for various

Finding a winning strategy in variations of Kayles

Database Management System Prof. D. Janakiram Department of Computer Science & Engineering Indian Institute of Technology, Madras Lecture No.

UMIACS-TR December, CS-TR-3192 Revised April, William Pugh. Dept. of Computer Science. Univ. of Maryland, College Park, MD 20742

Uncertain Data Models

PROCESSES AND THREADS

1. Introduction to Concurrent Programming

A Unifying Framework Supporting the Analysis and Development of Safe Regression Test Selection Techniques

Gen := 0. Create Initial Random Population. Termination Criterion Satisfied? Yes. Evaluate fitness of each individual in population.

A Comparison of Relativistic and Reader-Writer Locking Approaches to Shared Data Access

RTC: Language Support for Real-Time Concurrency

6.001 Notes: Section 8.1

Modeling and Simulating Discrete Event Systems in Metropolis

Synchronization Expressions: Characterization Results and. Implementation. Kai Salomaa y Sheng Yu y. Abstract

How useful is the UML profile SPT without Semantics? 1

A Mechanism for Sequential Consistency in a Distributed Objects System

Concurrent Objects and Linearizability

Discussion CSE 224. Week 4

Advanced Databases. Lecture 9- Concurrency Control (continued) Masood Niazi Torshiz Islamic Azad University- Mashhad Branch

Distributed minimum spanning tree problem

CHAPTER 4 AN INTEGRATED APPROACH OF PERFORMANCE PREDICTION ON NETWORKS OF WORKSTATIONS. Xiaodong Zhang and Yongsheng Song

Resource Sharing & Management

Key Range Locking Strategies for. David Lomet. Digital Equipment Corporation. Cambridge Research Lab. CRL 93/2 February 10, 1993

2 Addressing the Inheritance Anomaly One of the major issues in correctly connecting task communication mechanisms and the object-oriented paradigm is

An On-line Variable Length Binary. Institute for Systems Research and. Institute for Advanced Computer Studies. University of Maryland

Concurrent Reading and Writing of Clocks

loop m=5 d:m=x+y loop wait post u:z=3*m 7 20 end end

Höllische Programmiersprachen Hauptseminar im Wintersemester 2014/2015 Determinism and reliability in the context of parallel programming

Forward declaration of enumerations

Tilings of the Euclidean plane

Ch 9: Control flow. Sequencers. Jumps. Jumps

Concurrent Programming Lecture 3

Refine boundary at resolution r. r+1 r. Update context information CI(r) based on CI(r-1) Classify at resolution r, based on CI(r), update CI(r)

Autolink. A Tool for the Automatic and Semi-Automatic Test Generation

Introduction to Software Engineering

Breakpoints and Halting in Distributed Programs

Frank Mueller. Dept. of Computer Science. Florida State University. Tallahassee, FL phone: (904)

A Boolean Expression. Reachability Analysis or Bisimulation. Equation Solver. Boolean. equations.

21. Distributed Algorithms

Algorithms Implementing Distributed Shared Memory. Michael Stumm and Songnian Zhou. University of Toronto. Toronto, Canada M5S 1A4

Transcription:

A taxonomy of race conditions. D. P. Helmbold, C. E. McDowell UCSC-CRL-94-34 September 28, 1994 Board of Studies in Computer and Information Sciences University of California, Santa Cruz Santa Cruz, CA 95064 abstract Parallel programs are frequently non-deterministic, meaning they can give dierent results when provided the same input. These dierent results arise because variations in the timing of the multiple threads cause the threads to access shared resources in dierent orders. The phenomena that cause the non-deterministic behavior have been (and continue to be) variously referred to as access anomalies, race conditions or just races. In a recent paper, Netzer and Miller made an important contribution to formalizing and standardizing adjectives that can be applied to \races." In this paper we continue this eort by presenting a rened taxonomy for races in parallel programs. The terminology we suggest is not always consistent with that used previously and we describe why we believe our terminology is more descriptive. Categories and Subject Descriptors: D.1.3 [Programming Techniques]: Concurrent Programming, D.2.5 [Software Engineering]: Testing and Debugging - Debugging Aids, Tracing Additional Keywords and Phrases: trace analysis, race detection, event ordering This work was partially supported by the National Science Foundation grant # CCR-9102635.

1. Introduction 1 1 Introduction Parallel computers are an increasingly important part of high performance computing. A signicant number of these machines are programmed using a conventional language with extensions for creating threads 1 and some form of explicit synchronization (e.g. doall or fork with message passing). Many of these programs are intended to be deterministic, but due to synchronization errors are nondeterministic. Although some programs may be intentionally nondeterministic, errors can result in additional unwanted nondeterminism. In both cases it may be desirable to identify the sources of nondeterminism when debugging a program. This is particularly useful for those programs that are intended to be deterministic and might also be useful for intentionally nondeterministic programs provided the information about sources of nondeterminism is presented in a suitable manner. Informally, a \race" exists between two program events if they conict (e.g. one reads and the other writes the same memory location) and their execution order depends on how the threads are scheduled (this intuitive notion is formalized in Section 2). Before you can design and build a tool to detect races in parallel programs you must rst determine: What ordering relationships should hold between statement instances in a program? Having done that, you then build a tool to determine when those ordering relationships do not hold. In this paper we examine all possible ordering relationships that can hold between two program events and classify each possibility as either a non-race or belonging to one of four classes of races. We further rene our terminology for races by considering four additional orthogonal attributes of races: the aect on control ow, the severity, and the feasibility. 2 Events and Races Informally, an execution of a program contains a race if the result of some computational step depends upon the scheduling of the individual threads of execution 2. Netzer and Miller [NM92] developed a formal model of races that served as a starting point for our development. Their model includes two orthogonal attributes of races: with attributes general and data on one axis and feasible, apparent, and actual on the other axis. They dene a data race as a pair of conicting accesses that can overlap (i.e. are not atomic or protected by some type of critical section) and a general race as conicting accesses where the access order is not guaranteed. An actual race is one that actually occurred in a particular execution and only 1 For the purposes of this paper, thread, task and process are equivalent and we will use thread throughout. 2 Within this denition we assume that the values read from an external clock are part of the xed input rather than the result of a computational step. Without this assumption even sequential programs can give dierent results on dierent executions. The focus of this paper is on nondeterminism introduced by insucient synchronization.

2 2. Events and Races applies to general races. A feasible race, as the name suggests, is a race that did not occur but does occur in another execution. An apparent race is one that appears possible based only the limited information in a trace, but cannot occur. In the remainder of this section we formalize our notion of a race and extend Netzer and Miller's categorization. We assume that any thread's execution can be represented by a sequence of atomic operations. Denition 1: An event is a contiguous sequence of one or more atomic operations executed by a single thread. Although events are not necessarily atomic, we can represent each event by an atomic beginning and an atomic ending. For our purposes an execution of the program is any ordered list of event beginnings and endings that adheres to the program semantics. Note that dierent observers might see dierent execution orders when examining the same run of the program (see [Lam78]). This is not a problem as we are primarily interested in the set of all possible executions rather than identifying a single execution associated with a particular run of the program. Our denition of \event" is rather broad and can result in events that are \too big." In particular, if a single event may include several synchronization operations, the events may overlap in time but the subparts of the event that might cause a race could be properly ordered by the synchronization operations that are part of the event. This could result in spurious or harmless races being reported. In practice the events for a programming system should be suciently small to distinguish accesses to shared resources that are separated by synchronization. One example of how spurious races can be reported is when two properly synchronized tasks that access shared memory are treated in their entireties as single events. The two events would be concurrent and any shared accesses would also appear concurrent at this level of granularity. Some kinds of races require the identication of events across executions. We would like an equivalence relation allowing us to determine when two events from dierent executions are the same. Because events are associated with source statements, it is possible to draw conclusions about the program statements from which the events are derived. For our equivalence between events we treat any conditional access to a shared resource as if it were explicitly represented by the program's ow of control. For example, if array A[] is a set of shared variables then the assignment A[i] := expr is treated as a case statement that branches on the value of i. The main eect of this assumption is that all instances of a simple statement (Denition 2) access the same shared memory locations. Note, however, that dierent instances of a compound statement can access dierent memory locations. Furthermore, we treat the evaluation of the branch condition in a compound statment like a simple assignment statement. Denition 2: A simple statement is a syntactic portion of a program such that if any instruction in the machine level translation of the statement is executed every instruction from the machine level translation of the statement will be executed. A compound statement is any group of syntactically contiguous simple statements.

2. Events and Races 3 Denition 3: Two events in dierent executions of the same program are equal (i.e. can be considered to be the same event) if they occur in the same thread, their constituent atomic operations are derived from the same simple source program statements, and both events are the n th occurrence of their constituent atomic operation sequences by the thread. Thus an event is uniquely identied by its source program statements, the thread executing it, and a count indicating the number of times its source program statements have been previously executed by its thread. Two events are not the same if they represent the same compound statement but dierent simple statements. For example, the statement if (x=0) then x:=1; else x:=2; can be executed two dierent ways. The test can succeed, causing the execution of x:=1;, or the test can fail, causing the execution of x:=2. As these have dierent sequences of atomic operations they cannot be called the same event. Note also that two events are the same if they are the n th execution of their entire action sequences. Partial executions of their action sequences attributed to other events don't count. Consider the statement if (x=0) then x:=1; else x:=2; occurring in a loop which gets executed several times. Assume that the level of event granularity is such that each execution of this compound statement is represented by its own event (either a true; x:=1 event or a false; x:=2 event). Now the third true; x:=1 event in one execution is equal to the third true; x:=1 event in another execution, even if they occur in dierent iterations and/or after dierent numbers of false; x:=2 events. Denition 4: Let events e 1 and e 2 be two events occurring in an execution of a program. If e 1 completes before e 2 begins then we say e 1 happened before 3 e 2, written e 1!e 2. If e 1 begins before e 2 ends and e 2 begins before e 1 ends then the two events overlap. If either e 1 and e 2 overlap or e 1!e 2, then we write e 2 6!e 1. Note that the happened before and overlap relationships are for a particular execution and that if e 1!e 2 (or e 1 6!e 2 ) then both e 1 and e 2 occur in the execution. Denition 5: Fix an input to the program. Event e 1 is ordered before event e 2 if in every execution of the program on the input in which either event occurs, e 1!e 2. Two events, e 1 and e 2, are ordered if e 1 is ordered before e 2 or e 2 is ordered before e 1. Denition 6: Fix an input to the program. Event e 1 is semi-ordered before event e 2 if for that input every execution where both e 1 and e 2 occur, e 1!e 2, there exists an execution containing e 1 but not e 2 and every execution that contains e 2 also contains e 1. Two events, e 1 and e 2, are semi-ordered if e 1 is semi-ordered before e 2 or e 2 is semi-ordered before e 1. 3 This is a strictly temporal relation and should not be confused with Lamport's causal \happened before" relation [Lam78].

4 3. Ordering properties of Races Denition 7: Two events are unordered if they are neither ordered nor semi-ordered. Denition 8: Two simple statements conict if they both access the same shared resource and one (or both) of the accesses modies the resource. The accesses can be explicit as in access to a shared variable or implicit as in a communication port used for message passing. Denition 9: Two dierent events conict if they represent the execution of conicting simple statements. Denition 10: Fix an input to the program. If two conicting events are unordered (with respect to the input) then there is a race between the two events on the input. It is sometimes desirable to discuss races and the ordering relationships of statements in programs (in contrast to events in executions of programs). Denition 11: A program contains a race between statements s 1 and s 2 if there is an input I and events e 1 and e 2 such that: 1. e 1 represents the execution of an instance of s 1, 2. e 2 represents the execution of an instance of s 2, 3. s 1 and s 2 contain (or are) conicting simple statements, and 4. there is a race between e 1 and e 2 on input I. Note that a race between statements is a property of the program whereas a race between events is a property of the program/input pair. 3 Ordering properties of Races Each execution provides certain ordering or concurrency relationships between the events in the execution. A race exists for a particular input if there are two conicting events, e 1 and e 2, and either an execution (on that input) where e 1 and e 2 overlap or a pair of executions (on that input) where e 1!e 2 in one execution and e 2 happens before (or without) e 1 in the other. When only a single input is considered, we can classify races based on the relationships between the two events in the various executions. Given two events e 1 and e 2, there may be executions where: 1. e 1!e 2, 2. e 2!e 1, 3. e 1 and e 2 overlap, 4. e 1 occurs but e 2 does not, 5. e 2 occurs but e 1 does not, or 6. neither e 1 nor e 2 occur.

3. Ordering properties of Races 5 For any two events some set of the six possible orderings above will occur when all executions are considered. Given six distinct elements there are 64 (= 2 6 ) distinct sets possible. Each set potentially represents a dierent kind of event pair (e.g. always ordered, sometimes ordered, never ordered, never occur together...). Some of the 64 sets are not very interesting. The presence of Case 6 executions, where neither event occurs, does not aect the existence of races. This reduces the number of potentially interesting possibilities to 32 (see Table 3.1 below). Of these 32 combinations, two describe ordered events (1 only and 2 only), and two combinations describe semi-ordered events (1 with 4 and 2 with 5). In three other combinations at least one of the two events is never executed (4 only, 5 only, and none of 1{5). The remaining 25 combinations describe races. We divide these into four dierent kinds of races. Recall that races between events are with respect to a particular input. This provides the rst of four orthogonal attributes we will assign to a race. We call this the ordering attribute. concurrent race: In every execution of the program on the xed input where both e 1 and occur, they overlap. e 2 general race: There exist executions of the program on the xed input in which e 1 and e 2 overlap and executions where either e 1!e 2 or e 2!e 1. unordered race: There exist executions of the program on the xed input in which e 1!e 2 and executions in which e 2!e 1 but no execution in which e 1 and e 2 overlap. artifact race: There exist executions of the program on the xed input where e 2 occurs but e 1 does not and there exist executions where either e 1!e 2 or e 1 occurs but e 2 does not, but there are no executions on the xed input where either e 1 and e 2 are concurrent or e 2!e 1. Table 3.1 summarizes these denitions in the 29 cases where both e 1 and e 2 occur. Note that the denition of artifact races should be read as symmetric (if the conditions are met with e 1 and e 2 swapped, then it is still an artifact race). Our denition of a concurrent race may appear strange at rst (it did to us). If two events can happen at the same time, it would appear that either could happen before the other, especially if they do not contain synchronization primitives. The following two-thread code fragment gives one example of how events without synchronization must be executed concurrently. begin x:=1; if (x=0) then y:=0; end begin x:=0 y:=1 end The event \x:=1; test x; y:=0;" can only happen if variable x is set to zero concurrently. Thus if these are the only assignments to x, then the event \x:=1; test x; y:=0;" must occur concurrently with the event \x:=0; y:=1;" in the other thread. Netzer and Miller's [NM92] \data race" is equivalent to the union of both our concurrent races and general races. Specically they use data race to describe any race where the events do overlap in some execution. Our classication is more specic (i.e. it separates their data

6 4. Other attributes of races There exists executions where e 1!e 2 e 2!e 1 overlap e 1 only e 2 only yes yes yes y/n y/n general race yes yes no y/n y/n unordered race yes no yes y/n y/n general race yes no no y/n yes artifact race yes no no y/n no not a race no yes yes y/n y/n general race no yes no yes y/n artifact race no yes no no y/n not a race no no yes y/n y/n concurrent no no no yes yes artifact race Table 3.1: Summary of possible ordering relationships. races into two subgroups) and we believe the qualier \data" is more descriptive when used as we do below. We rene Netzer and Miller's term \general race" into our categories \concurrent", \general", and \unordered". We feel that this renement is useful, as the dierent kinds of races typically result from dierent kinds of errors. Unordered races are a particularly important category as they typically result from the use of mutual exclusion when a stronger kind of synchronization is required, such as using critical sections to protect non-associative or non-commutative modications to a shared variable. Concurrent races occur when two events interact in an unforeseen way, and mutual exclusion is an appropriate x. Our general races are similar to unordered races except that they indicate a total lack of synchronization rather than the presence of mutual exclusion. We have borrowed the term \artifact race" from Netzer and Miller [NM91], these races result from other races in the program. In their later paper [NM92] they do not mention artifact races and their denition of general and data races does not include what we now dene as artifact races. Although not identical to their earlier denition of \artifact," our denition is intuitively similar and hence our decision to use the same term. An artifact race can never be in the group of \rst" races (as dened in [NM91]). In particular, an artifact race has the property that the result of some \earlier" race aects the ow of control, preventing an event from being executed. This observation suggested an orthogonal attribute of races which we describe next. 4 Other attributes of races Races can have other important attributes in addition to their ordering properties. Here we briey discuss three other attributes: whether the race aects the program's control ow, the severity of the race, and the feasibility of the race.

4. Other attributes of races 7 4.1 Control vs Data A control race causes a thread to take dierent paths depending upon how the race is resolved. If the control ow is not aected by a race then it is a data race. By denition, every race involves conicting data accesses and could be intuitively thought of as a data race but we reserve data race for those races that only aect data and not control ow. 4.2 Severity A third potentially useful attribute of a race is its severity. We currently identify two severity levels, critical and benign. A benign race has no external eect on the results of the program (Padua and Emrath [EP88] call this internal non-determinism), while the outcome of a critical race can aect the program's result. Protecting a critical section with locks (mutual exclusion) does not prevent a race, but can make races benign. Consider the following code fragments with x initialized to zero. lock; lock; x := x + 1; x := x + 2; unlock; unlock; The two updates to x can happen in either order and thus create a race. However, the value of x is always three after both critical sections have been executed. Whenever a set of commutative updates to a shared variable must be completed before a variable is used and there are only unordered races between the updates, the races between updates are benign. This might not be the case if the two assignment statements were able to execute concurrently (so that both read the original value of x). Unordered races are often benign when they are caused by commutative 4 updates to a shared variable. The goal of at least one tool [Ste93] is to ignore the unordered races and report only concurrent and/or general races. 4.3 Feasibility Finally we note that previous work in race detection has distinguished between feasible and infeasible races [NM92]. This is really a characteristic of the race detection system which results from the need for approximate solutions. Any race that is reported but could never actually occur is infeasible. 4 Even when protected by locks, non-commutative updates (such as when the \x := x + 2;" statement is replaced by \x := x * 2;") are still likely to be sources of nondeterminism.

8 5. Conclusion 5 Conclusion We have presented a classication of races that includes four orthogonal attributes, event ordering, control versus data, severity and feasibility. Whenever possible we have adopted terminology that has been previously proposed. Our race taxonomy is complete in that it encompasses all possible races. It also separates races into dierent categories based on the type of error that typically causes that kind of race (e.g. unordered races indicate mutual exclusion was used when a stronger form of synchronization is necessary). Further renement is possible, but any type of race can be precisely categorized by our taxonomy (Table 3.1).

References 9 Acknowledgement The taxonomy of races was signicantly inuenced by an extended email dialogue with Rob Netzer. References [EP88] P. A. Emrath and D. A. Padua. Automatic detection of nondeterminacy in parallel programs. In Proc. Workshop on Parallel and Distributed Debugging, pages 89{99, May 1988. [Lam78] L. Lamport. Time, clocks, and the ordering of events in a distributed system. CACM, 21(7):558{565, July 1978. [NM91] R. H. B. Netzer and B. P. Miller. Improving the accuracy of data race detection. SIGPLAN Notices (Proc. PPOPP), 26(7):133{144, 1991. [NM92] Robert H.B. Netzer and Barton P. Miller. What are race conditions? Some issues and formalizations. ACM Letters on Programming Languages and Systems, pages 74{88, March 1992. [Ste93] N. Sterling. WARLOCK - a static data race analysis tool. In Proc. Winter Usenix, pages 97{106, 1993. End of paper. Total pages = 13.