Reference Capabilities for Concurrency and Scalability An Experience Report Elias Castegren , Tobias Wrigstad OCAP, Vancouver October 24th 2017 sa Structured Aliasing
What the CAP? • Object capability — An unforgeable reference to an object — The permission to perform (one or more) operations on that object { f oo, ba r } • Reference capability — An (unforgeable) object capability — The permission to perform (one or more) operations on that reference { f oo, ba r } {...}
This Talk • Reference capabilities for data-race freedom { f oo} {ba r } • Reference capabilities for atomic ownership transfer ∅ { f oo, ba r }
Warning: Aliasing May Cause Data-Races Boom!
Warning: Aliasing May Cause Data-Races ???
Warning: Aliasing May Cause Data-Races Aliasing doesn’t ??? Lack of mutual cause data-races! exclusion causes data-races!
Object Capabilities Are Not Enough • An object capability tells you something about what you can do with an object { f oo, ba r } • A reference capability implicitly tells you something about what others can do { f oo, ba r } {mo v e}
Kappa [ECOOP ’16]
Reference Capabilities for Concurrency Control • A capability grants access to some object reference • The type of a capability defines the interface to its object • A capability assumes exclusive access Thread-safety ⇒ No data-races • How thread-safety is achieved is x : T li nea r controlled by the capability’s mode
Reference Capabilities á la Mode • Exclusive modes li nea r l o c a l Globally unique Thread-local • Sharable modes ! r ead l o ck ed a ctiv e Precludes mutating Implicit locking Asynchronous actor aliases
⎭ Reference Capabilities á la Mode ⎫ li nea r l o c a l ⎬ Guarantee mutual exclusion l o ck ed a ctiv e r ead subo r d i na t e Precludes mutating Encapsulated aliases
Encore • Actor-based programming language
Encore • Actor-based programming language
Encore • Actor-based programming language • Uses reference capabilities to enforce safe sharing between actors
Encore • Actor-based programming language • Uses reference capabilities to enforce safe sharing between actors
Switching to a Delegating Model
Switching to a Delegating Model
Switching to a Delegating Model
Far References with Reference Capabilities { c op y } { f oo, ba r } ”a ctiv e” l o c a l { ! f oo, ! ba r } { c op y Nea r , c op y Fa r }
Taking Far References Further • Safely breaking encapsulation !
Taking Far References Further • Safely breaking encapsulation !
Actors without Borders [PLACES’17] !
Safe Object Sharing • Any two aliases are e.g. composable, synchronised, thread-local, encapsulated… ⇒ No data-races ! . . . • Whoever controls the aliasing controls the concurrency!
Pony [AGERE ’15] and Orca [OOPSLA’17] Thursday@OOPSLA 11:15-11:37
f Recap • Object capabilities specify the permitted operations on an object • Reference capabilities specify the permitted operations on a reference • Strictly following the reference capability model gives global guarantees : — Encapsulation — Thread-locality — Uniqueness — Absence of mutable aliases — …
Refcap > Ocap? Refcap ⇒ Ocap? Refcap ⊆ Ocap? • Reference capabilities can be a compliment to object capabilities • Reference capabilities allow specifying how object capabilities may be further shared — Shallow/transitive permission — Local/distributed permission • Can object capabilities ”emulate” reference capabilities? — Only partially • Can a reference capability be revoked? — Weak references
eliasc.github.io @CartesianGlee EliasC
Ensuring Mutual Exclusion • Relying on locks... • Relying on isolation… • Relying on immutability… • …bans shared mutable state altogether
Too restrictive? Ensuring Mutual Exclusion • Relying on locks... • Relying on isolation… • Relying on immutability… • …bans shared mutable state altogether
Example: A Treiber Stack s tr u ct Node { s tr u ct S t a ck { v a r e l em : T; v a r t op : Node; v a l nex t : Node; } } top next Stack N N N elem T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Example: A Treiber Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; oldTop } } oldTop top Stack N N N T T T
Fine-Grained Concurrency ≠ Mutual Exclusion de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } Shared Mutable state! Stack N N N T T T
Treiber Stack with Reference Capabilities and swap} { c ompa r e ∅ { r eadE l em} N {spe c u l a t e} Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } }
Treiber Stack with Reference Capabilities { c ompa r e … } ∅ { r eadE l em} N { … } and swap {spe c u l a t e} Stack de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } }
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } top {…} {…} Stack N N N T T T
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } ∅ top {…} {…} Stack N N N T T T
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } ∅ top {…} {…} Stack N N N T T T
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } {…} top {…} Stack N N N T T T
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; } } {…} {…} ∅ top Stack N N N T T T
Capability Transfer with Compare-and-Swap de f pop(s : S t a ck ) : T { wh il e ( tr ue) { v a l o l dTop = s. t op; if ( C AS(s. t op, o l dTop, o l dTop.nex t )) r e t u r n o l dTop.e l em; N } } ∅ {…} top Stack N N T T
LOLCAT [ECOOP ’17] • Linear Ownership: — At most one capability may access an object’s mutable fields • Three fundamental lock-free data-structures — Treiber Stack — Michael—Scott Queue — Tim Harris List • No uncontrolled data-races!
A Taxonomy of Reference Capabilities Capability Subordinate Exclusive Linear Local Shared Safe Unsafe … Pessimistic Oblivious Optimistic Atomic Lock-Free Locked Active Read Immutable
eliasc.github.io @CartesianGlee EliasC
Recommend
More recommend