140 likes | 240 Vues
This paper discusses Chalice, an experimental language focusing on shared-memory concurrency and static verification. Features include object-based memory, fractional permissions, locks, monitor invariants, deadlock prevention, and dynamic lock re-ordering. Permissions in Chalice involve dividing permissions between threads and monitors, with detailed predicate evaluations. Object life cycle and monitor invariants play a crucial role in ensuring correctness, while threads utilize fork/join for asynchronous calls. The paper also highlights preventing deadlocks through global ordering and advanced permissions like rd(o.x, n) for specifying read access. Through examples and detailed discussions, it presents an insightful perspective on concurrent programming.
E N D
Correct Concurrency with Chalice K. Rustan M. Leino Research in Software Engineering (RiSE)MSR Redmond Joint work with: Peter Müller, ETH ZurichJan Smans, KU Leuven INRIA-MSR 16 January 2009 Orsay, France
Chalice • Experimental language with focus on: • Share-memory concurrency • Static verification • Features: • Object/class-based memory (no subclassing) • Fractional-permissions model • Locks: mutual exclusion and readers/writers • Two-state monitor invariants • Deadlock prevention • Dynamic lock re-ordering
Permissions • Every memory location has an associated permission, which dynamically can be divided between threads and monitors • acc(o.x, p) specifies that the holder has p% permission to location o.x • acc(o.x) = acc(o.x, 100)
Encoding • Value of o.x is stored in Heap[o,x] • Current thread’s permission for o.x is stored in Mask[o,x] Mask Heap
Predicate evaluation • The evaluation of a predicate results in a transfer of permissions • For method M() requires Pre ensures Post • caller exhales Pre and inhales Post • calleeinhales Pre and exhales Post • Exhaling acc(o.x, p) amounts to: assert p ≤ Mask[o,x];Mask[o,x] := Mask[o,x] – p; • As in linear logic and separation logic, acc(o.x) acc(o.x) is equivalent to false
More about predicates • A predicate must be defined • o.x = 25 bad • acc(o.x) o.x = 25 good • Note that acc expressions can be guarded • o ≠ null acc(o.x) • acc expressions can appear only in positive positions in predicates
Object life cycle share thread local shared new release acquired unshare acquire
Monitor invariants • A monitor invariant holds when an object is in the shared state • class C { invariant J; … } • A monitor invariant must hold permissions for the locations it mentions
Monitor invariant checks share thread local shared new release acquired unshare acquire
Threads • Fork/join provide asynchronous calls • Roughly: • call o.M() • Exhale Pre; Inhale Post • fork o.M() • Exhale Pre • join o.M() • Inhale Post
Preventing deadlocks • When shared, an object is inserted into a global ordering among monitors • share p between o and q • Monitors must be acquired in ascending order • Position in locking order can be changed with the reorderstatement
-autoMagic • Filling in specifications to make them defined • o ≠ null acc(o.x) o.x = 5can be written just as:o.x = 5 • Demo: RockBand
Example • Hand-over-hand locking
Advanced permissions • A permission is a pair (p,n) • Intuitively, (p,n) represents the permission p + n* • rd(o.x, n) specifies n* • rd(o.x) = rd(o.x, 1) • rd(o.x, *) specifies an unbounded supply of ’s • Issue: good specification of read access