atomcaml: first-class atomicity via rollback michael f. ringenburg and dan grossman university of...
DESCRIPTION
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005 OCaml without atomic Shared memory programs in OCaml usually use locks. Shared memory programs in OCaml usually use locks. Typically used to form critical sections: Typically used to form critical sections: let critical lk th = try lock lk; let result = th () in unlock lk; result with e -> (unlock lk; raise e) unlocked output_ptr input_ptrTRANSCRIPT
AtomCaml: First-AtomCaml: First-class Atomicity via class Atomicity via
RollbackRollbackMichael F. Ringenburg and Dan Michael F. Ringenburg and Dan
GrossmanGrossmanUniversity of WashingtonUniversity of Washington
International Conference on Functional International Conference on Functional ProgrammingProgramming
September 26-28, 2005September 26-28, 2005
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
One New LineOne New Line This work boils down to one new line This work boils down to one new line
in Objective Caml’s in Objective Caml’s ThreadThread module: module:
This talk:This talk: Design: Atomic execution and fair Design: Atomic execution and fair
schedulingscheduling Implementation: Logging and RollbackImplementation: Logging and Rollback Evaluation: Experience and BenchmarksEvaluation: Experience and Benchmarks
external atomic: (unit->’a)->’a = “atomic”
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OCaml without OCaml without atomicatomic Shared memory Shared memory
programs in OCaml programs in OCaml usually use locks.usually use locks.
Typically used to form Typically used to form critical sections:critical sections:
let critical lk th = try lock lk; let result = th () in unlock lk; result with e -> (unlock lk; raise e)
unlocked
---
5
3
7
8
---
output_ptr
input_ptr
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OCaml without OCaml without atomicatomic
let critical lk th = try lock lk; let result = th () in unlock lk; result with e -> (unlock lk; raise e)
locked
---
5
3
7
8
---
output_ptr
input_ptr
Shared memory Shared memory programs in OCaml programs in OCaml usually use locks.usually use locks.
Typically used to form Typically used to form critical sections:critical sections:
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OCaml without OCaml without atomicatomic
let critical lk th = try lock lk; let result = th () in unlock lk; result with e -> (unlock lk; raise e)
locked
---
---
3
7
8
---
output_ptr
input_ptr
Shared memory Shared memory programs in OCaml programs in OCaml usually use locks.usually use locks.
Typically used to form Typically used to form critical sections:critical sections:
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OCaml without OCaml without atomicatomic
let critical lk th = try lock lk; let result = th () in unlock lk; result with e -> (unlock lk; raise e)
unlocked
---
---
3
7
8
---
output_ptr
input_ptr
Shared memory Shared memory programs in OCaml programs in OCaml usually use locks.usually use locks.
Typically used to form Typically used to form critical sections:critical sections:
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Some Problems with Some Problems with LocksLocks
locked
---
5
3
7
8
---
output_ptr
input_ptr
Race conditionsRace conditions A thread fails to A thread fails to
acquire the acquire the correct lock(s) correct lock(s) before accessing before accessing a shared object.a shared object.
DeadlockDeadlock A thread fails to A thread fails to
release a lock.release a lock.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Some Problems with Some Problems with LocksLocks
locked
---
---
3
7
8
---
output_ptr
input_ptr
Race conditionsRace conditions A thread fails to A thread fails to
acquire the acquire the correct lock(s) correct lock(s) before accessing before accessing a shared object.a shared object.
DeadlockDeadlock A thread fails to A thread fails to
release a lock.release a lock.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
AtomCaml: OCaml w/ AtomCaml: OCaml w/ atomicatomic
---
5
3
7
8
---
output_ptr
input_ptr
atomicatomic’s argument ’s argument executes as a executes as a single step, single step, withoutwithout any interleaving.any interleaving.
NoNo race conditions. race conditions. NoNo deadlock. deadlock.
let critical lk th = Thread.atomic th
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
AtomCaml: OCaml w/ AtomCaml: OCaml w/ atomicatomic
---
5
3
7
8
---
output_ptr
input_ptr
let critical th = Thread.atomic th
atomicatomic’s argument ’s argument executes as a executes as a single step, single step, withoutwithout any interleaving.any interleaving.
NoNo race conditions. race conditions. NoNo deadlock. deadlock.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
AtomCaml: OCaml w/ AtomCaml: OCaml w/ atomicatomic
---
---
3
7
8
---
output_ptr
input_ptr
let critical th = Thread.atomic th
atomicatomic’s argument ’s argument executes as a executes as a single step, single step, withoutwithout any interleaving.any interleaving.
NoNo race conditions. race conditions. NoNo deadlock. deadlock.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OutlineOutline Design of AtomCamlDesign of AtomCaml
Semantics of atomic and exceptionsSemantics of atomic and exceptions The The yield_ryield_r primitive primitive
ImplementationImplementation Logging, Rollback, and ClosuresLogging, Rollback, and Closures Takes advantage of OCaml's Takes advantage of OCaml's
uniprocessor restriction.uniprocessor restriction. EvaluationEvaluation Related and future workRelated and future work
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Design:Design: The The atomicatomic PrimitivePrimitive
Takes a thunked block of code (the Takes a thunked block of code (the “atomic block”), and executes it with “atomic block”), and executes it with no interleaving.no interleaving.
The atomic block may contain almost The atomic block may contain almost any valid Caml code, including:any valid Caml code, including: Function calls to external C codeFunction calls to external C code ExceptionsExceptions Buffered outputBuffered output
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Design:Design: Exceptions Exceptions Two choices if an exception escapes an atomic Two choices if an exception escapes an atomic
block: block: keep the block’s effectskeep the block’s effects or or discard its discard its effectseffects..
We chose to keep effects:We chose to keep effects: Exceptions are merely non-local control transfer. Exceptions are merely non-local control transfer.
When control leaves atomic block, it commits.When control leaves atomic block, it commits. Atomic blocks should behave like sequential code.Atomic blocks should behave like sequential code. Exception may depend on effects.Exception may depend on effects. The alternative may cause unexpected errors:The alternative may cause unexpected errors:
let x = ref 0atomic (fun () -> x := 1; f () (* may raise exception *))if !x = 0 then failwith “huh” else ...
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Design:Design: The The yield_ryield_r PrimitivePrimitive
atomic (fun () -> while (is_empty bbuf) do yield_r (bbuf.input_ptr) done; ... (* remove item *))
---
---
---
output_ptr
input_ptr
Often wish to wait for a specific condition Often wish to wait for a specific condition to hold before attempting a critical section.to hold before attempting a critical section. E.g., wait until the buffer is non-empty before E.g., wait until the buffer is non-empty before
removing an item.removing an item. Like guards and conditional critical regionsLike guards and conditional critical regions
We use the We use the yield_ryield_r primitive to achieve a primitive to achieve a similar effect (see paper).similar effect (see paper).
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Design:Design: The The yield_ryield_r PrimitivePrimitive
---
5
---
output_ptr
input_ptr
atomic (fun () -> while (is_empty bbuf) do yield_r (bbuf.input_ptr) done; ... (* remove item *))
Often wish to wait for a specific condition Often wish to wait for a specific condition to hold before attempting a critical section.to hold before attempting a critical section. E.g., wait until the buffer is non-empty before E.g., wait until the buffer is non-empty before
removing an item.removing an item. Like guards and conditional critical regionsLike guards and conditional critical regions
We use the We use the yield_ryield_r primitive to achieve a primitive to achieve a similar effect (see paper).similar effect (see paper).
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Design:Design: The The yield_ryield_r PrimitivePrimitive
---
---
---
output_ptr
input_ptr
atomic (fun () -> while (is_empty bbuf) do yield_r (bbuf.input_ptr) done; ... (* remove item *))
Often wish to wait for a specific condition Often wish to wait for a specific condition to hold before attempting a critical section.to hold before attempting a critical section. E.g., wait until the buffer is non-empty before E.g., wait until the buffer is non-empty before
removing an item.removing an item. Like guards and conditional critical regionsLike guards and conditional critical regions
We use the We use the yield_ryield_r primitive to achieve a primitive to achieve a similar effect (see paper).similar effect (see paper).
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OutlineOutline Design of AtomCamlDesign of AtomCaml
Semantics of atomic and exceptionsSemantics of atomic and exceptions The The yield_ryield_r primitive primitive
ImplementationImplementation Logging, Rollback, and ClosuresLogging, Rollback, and Closures Takes advantage of OCaml's Takes advantage of OCaml's
uniprocessor restriction.uniprocessor restriction. EvaluationEvaluation Related and future workRelated and future work
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: OverviewOverview
Atomic blocksAtomic blocks If a thread executing an atomic block is If a thread executing an atomic block is
preempted, rollback and retry laterpreempted, rollback and retry later Otherwise, the block executed with no Otherwise, the block executed with no
interleaving (OCaml runs as a uniprocessor)interleaving (OCaml runs as a uniprocessor) SchedulingScheduling
Allow preemption, so fairness is ensuredAllow preemption, so fairness is ensured Allocate extra time to threads with long Allocate extra time to threads with long
atomic blocks, and skip rounds to maintain atomic blocks, and skip rounds to maintain fairnessfairness
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: AssumptionsAssumptions
Most atomic blocks will be short, so Most atomic blocks will be short, so rollbacks will be rare.rollbacks will be rare. Optimize for the common case (no Optimize for the common case (no
rollback)rollback) Only a small percentage of code will Only a small percentage of code will
execute inside atomic blocks.execute inside atomic blocks. Add as little overhead as possible to Add as little overhead as possible to
non-atomic codenon-atomic code
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
Two choices for reversing effects:Two choices for reversing effects: Record effects in an undo log and reverse on Record effects in an undo log and reverse on
rollbackrollback Store effects in a commit log and execute on Store effects in a commit log and execute on
completion.completion. Memory writes: undo logMemory writes: undo log Output: commit log (buffer)Output: commit log (buffer)
7338
x Log
x := 6337
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
Memory writes: undo logMemory writes: undo log Makes reads in atomic faster - can execute Makes reads in atomic faster - can execute
directly, rather than checking log.directly, rather than checking log. Only need to log writes to mutable variablesOnly need to log writes to mutable variables No need to log outside of atomic blocksNo need to log outside of atomic blocks
Output: commit log (buffer)Output: commit log (buffer) Can’t “reverse” already-viewed writesCan’t “reverse” already-viewed writes
7338
x Log
x := 6337
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
6337
x Log
x := 4242 (&x,7338)
Memory writes: undo logMemory writes: undo log Makes reads in atomic faster - can execute Makes reads in atomic faster - can execute
directly, rather than checking log.directly, rather than checking log. Only need to log writes to mutable variablesOnly need to log writes to mutable variables No need to log outside of atomic blocksNo need to log outside of atomic blocks
Output: commit log (buffer)Output: commit log (buffer) Can’t “reverse” already-viewed writesCan’t “reverse” already-viewed writes
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
4242
x Log
Rollback (&x,7338)
(&x,6337)
Memory writes: undo logMemory writes: undo log Makes reads in atomic faster - can execute Makes reads in atomic faster - can execute
directly, rather than checking log.directly, rather than checking log. Only need to log writes to mutable variablesOnly need to log writes to mutable variables No need to log outside of atomic blocksNo need to log outside of atomic blocks
Output: commit log (buffer)Output: commit log (buffer) Can’t “reverse” already-viewed writesCan’t “reverse” already-viewed writes
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
6337
x Log
Rollback (&x,7338)
Memory writes: undo logMemory writes: undo log Makes reads in atomic faster - can execute Makes reads in atomic faster - can execute
directly, rather than checking log.directly, rather than checking log. Only need to log writes to mutable variablesOnly need to log writes to mutable variables No need to log outside of atomic blocksNo need to log outside of atomic blocks
Output: commit log (buffer)Output: commit log (buffer) Can’t “reverse” already-viewed writesCan’t “reverse” already-viewed writes
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: RollbackRollback
7338
x Log
Rollback
Memory writes: undo logMemory writes: undo log Makes reads in atomic faster - can execute Makes reads in atomic faster - can execute
directly, rather than checking log.directly, rather than checking log. Only need to log writes to mutable variablesOnly need to log writes to mutable variables No need to log outside of atomic blocksNo need to log outside of atomic blocks
Output: commit log (buffer)Output: commit log (buffer) Can’t “reverse” already-viewed writesCan’t “reverse” already-viewed writes
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Implementation:Implementation: FunctionsFunctions
Functions called in atomic blocks must log Functions called in atomic blocks must log and buffer.and buffer.
We create two versions of each function: We create two versions of each function: atomic (logs and buffers) and non-atomic. atomic (logs and buffers) and non-atomic.
Closures contain pointers to both.Closures contain pointers to both. We know at compile-time which pointer to We know at compile-time which pointer to
follow, so we just insert the appropriate follow, so we just insert the appropriate byte code.byte code.
Atomic Code Pointer
Free VariableFree Variable
Atomic FunctionNon-atomic Code Pointer
Non-atomic Function
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Calling External C Calling External C FunctionsFunctions
external foo: type = “c_foo”
The programmer must tell AtomCaml how The programmer must tell AtomCaml how to handle external calls in an atomic block.to handle external calls in an atomic block.
If the function can be called safely as is If the function can be called safely as is (e.g., it only modifies local state):(e.g., it only modifies local state):
If the programmer provides a separate, If the programmer provides a separate, atomic-safe version:atomic-safe version:
If a function should never be called in an If a function should never be called in an atomic:atomic:
external foo: type = “c_foo_non c_foo_atom”
external foo: type = “c_foo raise_on_atomic”
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Calling External C Calling External C FunctionsFunctions
To construct atomic-safe versions of To construct atomic-safe versions of C functions, programmers must be C functions, programmers must be able to:able to: Specify actions that should occur if the Specify actions that should occur if the
block is rolled back (e.g., reversing block is rolled back (e.g., reversing write):write):
Specify actions that should be delayed Specify actions that should be delayed until the block commits (e.g., output):until the block commits (e.g., output):
caml_register_rollback_action(func, env)
caml_register_commit_action(func, env)
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OutlineOutline Design of AtomCamlDesign of AtomCaml
Semantics of atomic and exceptionsSemantics of atomic and exceptions The The yield_ryield_r primitive primitive
ImplementationImplementation Logging, Rollback, and ClosuresLogging, Rollback, and Closures Takes advantage of OCaml's Takes advantage of OCaml's
uniprocessor restriction.uniprocessor restriction. EvaluationEvaluation Related and future workRelated and future work
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Evaluation:Evaluation: PLANet PLANet Active networking system written in OCaml. We Active networking system written in OCaml. We
ported it to AtomCaml (we replaced all locks).ported it to AtomCaml (we replaced all locks). No significant structural changes were No significant structural changes were
required.required. Had to create atomic safe versions of three C Had to create atomic safe versions of three C
functions:functions: Two output functions (we buffered)Two output functions (we buffered) One killed a thread (we delayed)One killed a thread (we delayed)
Moved three other C calls out of atomicMoved three other C calls out of atomic Converting to atomic fixed (at least) three Converting to atomic fixed (at least) three
concurrency bugs, without any effort.concurrency bugs, without any effort.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Evaluation:Evaluation: Benchmarks Benchmarks
BenchmarkBenchmark OCamlOCaml AtomCaAtomCamlml
OverheaOverheadd
Web CacheWeb Cache 7.630 7.630 secsec
7.689 sec7.689 sec 0.8%0.8%
PLANet pingPLANet ping 1.150 1.150 secsec
1.198 sec1.198 sec 4.2%4.2%
PLANet sendPLANet send 0.074 0.074 secsec
0.067 sec0.067 sec (-9.4%)(-9.4%)
PLANet PLANet receivereceive
0.084 0.084 secsec
0.090 sec0.090 sec 7.0%7.0%
Overhead of non-atomic, single-threaded Overhead of non-atomic, single-threaded benchmarks ≈ 2%benchmarks ≈ 2% Alternate closures (see paper) sped up sequential Alternate closures (see paper) sped up sequential
code, but slowed down concurrent code.code, but slowed down concurrent code. Overhead of real concurrent applications:Overhead of real concurrent applications:
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
OutlineOutline Design of AtomCamlDesign of AtomCaml
Semantics of atomic and exceptionsSemantics of atomic and exceptions The The yield_ryield_r primitive primitive
ImplementationImplementation Logging, Rollback, and ClosuresLogging, Rollback, and Closures Takes advantage of OCaml's Takes advantage of OCaml's
uniprocessor restriction.uniprocessor restriction. EvaluationEvaluation Related and future workRelated and future work
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Related WorkRelated Work Harris et al.’s Haskell with transactionsHarris et al.’s Haskell with transactions
Uses an STM monad to provide atomicityUses an STM monad to provide atomicity Also provides sequential and alternative Also provides sequential and alternative
compositioncomposition Many other atomicity implementations, e.g.,Many other atomicity implementations, e.g.,
Harris and Fraser’s Java transactionsHarris and Fraser’s Java transactions Manson et al.’s real-time JavaManson et al.’s real-time Java
Concurrent MLConcurrent ML Asynchronous message-passing style concurrencyAsynchronous message-passing style concurrency OCaml CML uses a master lock, which we OCaml CML uses a master lock, which we
replaced with atomic.replaced with atomic.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Future WorkFuture Work More efficient logging and rollbackMore efficient logging and rollback Only generate dual versions of Only generate dual versions of
functions that might be called in functions that might be called in atomic blocksatomic blocks May eliminate as much as 90% of code May eliminate as much as 90% of code
bloatbloat Multiprocessor support: Already Multiprocessor support: Already
working on AtomJavaworking on AtomJava
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
ConclusionsConclusions We designed, implemented an evaluated We designed, implemented an evaluated
AtomCaml.AtomCaml. Extension to Objective Caml that supports Extension to Objective Caml that supports
atomic critical sectionsatomic critical sections Using a logging-and-rollback approach to Using a logging-and-rollback approach to
guarantee atomicityguarantee atomicity Ensures fair scheduling by allowing preemptionEnsures fair scheduling by allowing preemption Low overhead on real applicationsLow overhead on real applications
Atomicity offers a higher-level, stronger, Atomicity offers a higher-level, stronger, easier-to-reason about synchronization easier-to-reason about synchronization guarantee than locks.guarantee than locks.
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Evaluation:Evaluation: Benchmarks Benchmarks Logging and rollback overhead:Logging and rollback overhead:
Locks vs. Atomic:Locks vs. Atomic:BlockBlock LocksLocks AtomicAtomic OverheaOverhea
dd0 Writes0 Writes 0.988 0.988
secsec1.015 sec1.015 sec 115%115%
5 Writes5 Writes 0.584 0.584 secsec
0.594 sec0.594 sec 108%108%
10 Writes10 Writes 3.483 3.483 secsec
3.440 sec3.440 sec 82%82%
September 26, 2005 AtomCaml: First-Class Atomicity via Rollback ICFP 2005
Evaluation:Evaluation: Benchmarks Benchmarks Overhead of non-atomic code:Overhead of non-atomic code:
BenchmarkBenchmark OCamlOCaml AtomCaAtomCamlml
OverheaOverheadd
Compile 1Compile 1 0.988 0.988 secsec
1.015 sec1.015 sec 2.7%2.7%
Compile 2Compile 2 0.584 0.584 secsec
0.594 sec0.594 sec 1.6%1.6%
CDS InterpretCDS Interpret 3.483 3.483 secsec
3.440 sec3.440 sec 1.3%1.3%