In this paper we introduce a new method for pessimistically implementing composable, nestable atomic statements. Our mechanism, called shelters, is inspired by the synchronization strategy used in the Jade programming language. Unlike previous lock-based pessimistic approaches, our mechanism does not require a whole-program analysis that computes a global lock order. Further, this mechanism frees us to implement several optimizations, impossible with automatically inserted locks, that are necessary for scaling on recent multi-core systems. Additionally we show how our basic mechanism can be extended to support both open- and closed-nesting of atomic statements, something that, to our knowledge, has not yet been implemented fully-pessimistically in this context. Unlike optimistic, transactional-memory-based approaches, programmers using our mechanism do not have to write compensating actions for open-nesting, or worry about the possibly awkward semantics and performance impact of aborted transactions.
Similar to systems using locks, our implementation requires programmers to annotate the types of objects with the shelters that protect them, and indicate the sections of code to be executed atomically with atomic statements. A static analysis then determines from which shelters protection is needed for the atomic statements to run atomically. We have implemented shelter-based atomic statements for C, and applied our implementation to 12 benchmarks totaling over 200k lines of code including the STAMP benchmark suite, and the sqlite database system. Our implementation’s performance is competitive with explicit locking, Autolocker, and a mature software transactional memory implementation.