Operating Systems
Fall 2014
Synchronization
Myungjin Lee myungjin.lee@ed.ac.uk
1
Operating Systems Fall 2014 Synchronization Myungjin Lee - - PowerPoint PPT Presentation
Operating Systems Fall 2014 Synchronization Myungjin Lee myungjin.lee@ed.ac.uk 1 Temporal relations Instructions executed by a single thread are totally ordered A < B < C < Absent synchronization, instructions executed
1
2
3
main()
pthread_create()
foo()
4
5
is the “happens-before” relation
6
7
int withdraw(account, amount) { int balance = get_balance(account); // read balance -= amount; // modify put_balance(account, balance); // write spit out cash; }
8
9 int withdraw(account, amount) { int balance = get_balance(account); balance -= amount; put_balance(account, balance); spit out cash; } int withdraw(account, amount) { int balance = get_balance(account); balance -= amount; put_balance(account, balance); spit out cash; }
10 balance = get_balance(account); balance -= amount; balance = get_balance(account); balance -= amount; put_balance(account, balance); spit out cash; put_balance(account, balance); spit out cash;
Execution sequence as seen by CPU context switch context switch
11 int withdraw(account, amount) { int balance = get_balance(account); balance -= amount; put_balance(account, balance); spit out cash; } int withdraw(account, amount) { int balance = get_balance(account); balance -= amount; put_balance(account, balance); spit out cash; }
12 int xfer(from, to, amt) { withdraw( from, amt ); deposit( to, amt ); } int xfer(from, to, amt) { withdraw( from, amt ); deposit( to, amt ); }
13 i++; i++;
14
15
16
17
Two choices:
18
19 int withdraw(account, amount) { acquire(lock); balance = get_balance(account); balance -= amount; put_balance(account, balance); release(lock); spit out cash; } acquire(lock) balance = get_balance(account); balance -= amount; balance = get_balance(account); balance -= amount; put_balance(account, balance); release(lock); spit out cash; put_balance(account, balance); release(lock); acquire(lock)
critical section
spit out cash;
20
21 struct lock_t { int held = 0; } void acquire(lock) { while (lock->held); lock->held = 1; } void release(lock) { lock->held = 0; } the caller “busy-waits”,
released ⇒ hence spinlock
22
23 bool test_and_set(bool *flag) { bool old = *flag; *flag = True; return old; }
24 struct lock { int held = 0; } void acquire(lock) { while(test_and_set(&lock->held)); } void release(lock) { lock->held = 0; }
25 int withdraw(account, amount) { acquire(lock); balance = get_balance(account); balance -= amount; put_balance(account, balance); release(lock); spit out cash; } acquire(lock) balance = get_balance(account); balance -= amount; balance = get_balance(account); balance -= amount; put_balance(account, balance); release(lock); spit out cash; put_balance(account, balance); release(lock); acquire(lock)
critical section
spit out cash;
26
27 struct lock { } void acquire(lock) { cli(); // disable interrupts } void release(lock) { sti(); // reenable interrupts }
28
29
30