One of the major productivity hurdles for parallel programming is non-determinism -- a parallel program may yield different results on different executions with the same input, depending on the order in which operations are interleaved. A major source of non-determinism is data races, and checking for the absence of data races is an important candidate for runtime verification. Past work on data race detection includes different techniques for different programming models such as SPMD, fork-join, and monitors. However, the runtime overheads incurred by past techniques are still prohibitively large (often a slowdown of 10