Synchronization 2: Locks (part 2), Mutexes
1
Synchronization 2: Locks (part 2), Mutexes 1 load/store reordering - - PowerPoint PPT Presentation
Synchronization 2: Locks (part 2), Mutexes 1 load/store reordering recall: out-of-order processors processors execute instructons in difgerent order hide delays from slow caches, variable computation rates, etc. convenient optimization:
1
2
3
Source: Intel 64 and IA-32 Software Developer’s Manual, Volume 3A, Chapter 8
4
5
6
6
7
7
7
8
9
10
11
12
13
14
15
16
17
17
18
19
19
20
20
20
21
21
21
21
21
21
22
23
24
25
26
27
28
28
29
30
30
30
30
30
31
32
33
34
35
36
37
37
37
37
38
38
38
38
39
39
39
39
40
41
address value state lock locked Modifjed address value state lock
address value state lock
42
address value state lock
address value state lock locked Modifjed address value state lock
42
address value state lock
address value state lock
address value state lock locked Modifjed
42
address value state lock
address value state lock locked Modifjed address value state lock
42
address value state lock
address value state lock
address value state lock locked Modifjed
42
address value state lock unlocked Modifjed address value state lock
address value state lock Invalid
42
address value state lock
address value state lock locked Modifjed address value state lock Invalid
42
43
44
address value state lock locked Modifjed address value state lock
address value state lock
45
address value state lock locked Modifjed address value state lock Invalid address value state lock Invalid
45
address value state lock locked Shared address value state lock locked Shared address value state lock Invalid
45
address value state lock locked Shared address value state lock locked Shared address value state lock locked Shared
45
address value state lock locked Shared address value state lock locked Shared address value state lock locked Shared
45
address value state lock lockedunlocked Modifjed address value state lock
address value state lock
45
address value state lock locked Modifjed address value state lock Invalid address value state lock Invalid
45
46
47
48
49
10 20 30 40 50 60 70 distance between array elements (bytes) 100000000 200000000 300000000 400000000 500000000 time (cycles)
50
51
52
53
54
54
54
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
LockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->lock_taken) { put current thread on m->wait_queue make current thread not runnable /* xv6: myproc()->state = SLEEPING; */ UnlockSpinlock(&m->guard_spinlock); run scheduler } else { m->lock_taken = true; UnlockSpinlock(&m->guard_spinlock); } } UnlockMutex(Mutex *m) { LockSpinlock(&m->guard_spinlock); if (m->wait_queue not empty) { remove a thread from m->wait_queue make that thread runnable /* xv6: myproc()->state = RUNNABLE; */ } else { m->lock_taken = false; } UnlockSpinlock(&m->guard_spinlock); }
55
56
57
58
59
60
61
62
63
63
64
65
66
66
66
67