synchronization 2: locks / memory ordering
1
synchronization 2: locks / memory ordering 1 last time pthread - - PowerPoint PPT Presentation
synchronization 2: locks / memory ordering 1 last time pthread create/join racing where data is stored in stacks/etc. (not) making locks from atomic load/store making locks (started) 2 implementing locks: single core intuition: context
1
2
3
3
4
4
4
5
5
5
5
6
7
8
8
9
9
10
11
Source: Intel 64 and IA-32 Software Developer’s Manual, Volume 3A, Chapter 8
12
13
14
14
15
15
15
16
17
18
19
20
21
22
23
24
25
26
27
28
28
29
30
30
31
31
31
32
32
32
32
32
32
33
34
35
36
37
38
39
39
40
41
41
41
41
41
42
43
44
45
46
47
48
48
48
48
49
49
49
49
50
50
50
50
51
52
address value state lock locked Modifjed address value state lock
address value state lock
53
address value state lock
address value state lock locked Modifjed address value state lock
53
address value state lock
address value state lock
address value state lock locked Modifjed
53
address value state lock
address value state lock locked Modifjed address value state lock
53
address value state lock
address value state lock
address value state lock locked Modifjed
53
address value state lock unlocked Modifjed address value state lock
address value state lock Invalid
53
address value state lock
address value state lock locked Modifjed address value state lock Invalid
53
54
55
56
address value state lock locked Modifjed address value state lock
address value state lock
57
address value state lock locked Modifjed address value state lock Invalid address value state lock Invalid
57
address value state lock locked Shared address value state lock locked Shared address value state lock Invalid
57
address value state lock locked Shared address value state lock locked Shared address value state lock locked Shared
57
address value state lock locked Shared address value state lock locked Shared address value state lock locked Shared
57
address value state lock lockedunlocked Modifjed address value state lock
address value state lock
57
address value state lock locked Modifjed address value state lock Invalid address value state lock Invalid
57
58
59
60
61
10 20 30 40 50 60 70 distance between array elements (bytes) 100000000 200000000 300000000 400000000 500000000 time (cycles)
62
63
64
65
66
66
67
67
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); }
68
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); }
68
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); }
68
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); }
68
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); }
68
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); }
68
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); }
68
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); }
68
69
70
71
72
73
74
75
76
76
77
78
79
79
79
80
81
82
83
84
85
85
85
85
85
85
86
87
88
89