locks do not compose
play

Locks Do Not Compose! Example Code Thread 1 Thread 2 class - PowerPoint PPT Presentation

Locks Do Not Compose! Example Code Thread 1 Thread 2 class Account { transfer(A, B, 10); transfer(B, A, 10); float balance; -> call A.lock() -> call B.lock() void deposit(float amt) { -> call B.lock() -> call A.lock()


  1. Locks Do Not Compose! Example Code Thread 1 Thread 2 class Account { transfer(A, B, 10); transfer(B, A, 10); float balance; -> call A.lock() ① -> call B.lock() ② void deposit(float amt) { -> call B.lock() ③ -> call A.lock() ④ this.lock(); balance += amt; this.unlock(); } void withdraw(float amt) { • Deadlock!!! this.lock(); balance -= amt; • Changing order of from.lock() and this.unlock(); to.lock() inside transfer(…) will not } } solve problem … • Need elaborate scheme to ensure void transfer(Account from, Account to, float amt) { from.lock(); to.lock(); uniform lock ordering among from.withdraw(amt); Acount objects for each new type to.deposit(amt); to.unlock(); from.unlock(); of transaction }  Not Composable!

  2. Converting to a TM Paradigm Example Code TM Code class Account { class Account { float balance; float balance; void deposit(float amt) { void deposit(float amt) { this.lock(); begin_atomic; balance += amt; balance += amt; this.unlock(); end_atomic; } } void withdraw(float amt) { void withdraw(float amt) { this.lock(); begin_atomic; balance -= amt; balance -= amt; this.unlock(); end_atomic; } } } } … … void transfer(Account from, Account to, float amt) { void transfer(Account from, Account to, float amt) { from.lock(); to.lock(); begin_atomic; from.withdraw(amt); from.withdraw(amt); to.deposit(amt); to.deposit(amt); to.unlock(); from.unlock(); end_atomic; } }  Now no Deadlocks! (Roll back on atomicity violation)

  3. Open vs. Closed Nesting Thread 1 Thread 2 Example Code class List { foo(list, x, y); bar(list, z); void insert(Object o) { -> call list.insert(x); ① -> call list.insert(z) ② begin_atomic; -> call list.insert(y); ③ … end_atomic; • } Can list ordering x, z, y happen? … – No: Closed Nesting } – void foo(List list, Object o) { Yes: Open Nesting … • Closed Nesting list.insert(o); – … Inner transaction state merged to outer } transaction on commit void bar(List list, Object x, Object y) { – Preserves atomicity of outer transaction /* nested transaction */ – begin_atomic; Most intuitive to programmers … • Open Nesting list.insert(x); – list.insert(y); Inner transaction state merged to main memory … on commit end_atomic; – Breaks atomicity of outer transaction } – Needs compensating code – Allows interleaving w/o squashing (e.g. malloc)

Recommend


More recommend