Multiprocessor
synchronization algorithms
(20225241)
Local-Spin Mutual Exclusion
Lecturer: Danny Hendler
This presentation is based on the book “Synchronization Algorithms and Concurrent
Programming” by G. Taubenfeld and on a the survey “Shared-memory mutual
exclusion: major research trends since 1986” by J. Anderson, Y-J. Kim and T.
Herman
Remote and local memory accesses
In a DSM system:
local
remote
In a Cache-coherent system:
An access of v by p is remote if it is the first
access of v or if v has been written by
another process since p’s last access of it.
Local-spin algorithms
• In a local-spin algorithm, all busy waiting (‘await’) is done
by read-only loops of local-accesses, that do not cause
interconnect traffic.
• The same algorithm may be local-spin on one architecture
(DSM or CC) and non-local spin on the other.
For local-spin algorithms, our complexity metric is the
worst-case number of Remote Memory References (RMRs)
Peterson’s 2-process algorithm
Program for process 0
Program for process 1
1.
2.
3.
4.
5.
1.
2.
3.
4.
5.
b[0]:=true
turn:=0
await (b[1]=false or turn=1)
CS
b[1]:=false
b[1]:=true
turn:=1
await (b[0]=false or turn=0)
CS
b[1]:=false
Is this algorithm local-spin on a DSM machine?
Is this algorithm local-spin on a CC machine?
No
Yes
Local Spinning Mutual Exclusion
Using Strong Primitives
Anderson’s queue-based algorithm
(Anderson, 1990)
Shared:
integer ticket – A RMW object, initially 0
bit valid[0..n-1], initially valid[0]=1 and valid[i]=0, for i{1,..,n-1}
Local:
integer myTicket
valid
ticket
0
1
2
3
n-1
1
0
0
0
0
Program for process i
1.
2.
3.
4.
5.
myTicket=fetch-and-inc-modulo-n(ticket) ; take a ticket
await valid[myTicket]=1 ; wait for your turn
CS
valid[myTicket]:=0 ; dequeue
valid[myTicket + 1 mod n]:=1 ; signal successor
Anderson’s queue-based algorithm (cont’d)
After entry section of p3
Initial configuration
myTicket3
ticket
0
valid
1
0
0
0
0
ticket
1
valid
1
After p1 performs entry section
ticket
2
valid
1
myTicket3
myTicket1
0
1
0
0
0
0
0
0
0
0
0
After p3 exits
myTicket1
ticket
2
valid
0
1
1
0
0
0
Anderson’s queue-based algorithm (cont’d)
Program for process i
1.
2.
3.
4.
5.
myTicket=fetch-and-inc-modulo-n(ticket) ; take a ticket
await valid[myTicket]=1 ; wait for your turn
CS
valid[myTicket]:=0 ; dequeue
valid[myTicket + 1 mod n]:=1 ; signal successor
What is the RMR complexity on a DSM machine? Unbounded
What is the RMR complexity on a CC machine? Constant
The MCS queue-based algorithm
(Mellor-Crummey and Scott, 1991)
• Has constant RMR complexity under both the DSM and
CC models
• Uses swap and CAS
Type:
Qnode: structure {bit locked, Qnode *next}
Shared:
Qnode nodes[0..n-1]
Qnode *tail initially null
Local:
Qnode *myNode, initially &nodes[i]
Qnode *successor
Tail
nodes
F
1
T
2
T
3
n-1
n
The MCS queue-based algorithm (cont’d)
Program for process i
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
myNode->next := null; prepare to be last in queue
pred=swap(&tail, myNode ) ;tail now points to myNode
if (pred ≠ null) ;I need to wait for a predecessor
myNode->locked := true ;prepare to wait
pred->next := myNode ;let my predecessor know it has to unlock me
await myNode.locked := false
CS
if (myNode.next = null) ; if not sure there is a successor
if (compare-and-swap(&tail, myNode, null) = false) ; if there is a successor
await (myNode->next ≠ null) ; spin until successor lets me know its identity
successor := myNode->next ; get a pointer to my successor
successor->locked := false ; unlock my successor
else ; for sure, I have a successor
successor := myNode->next ; get a pointer to my successor
successor->locked := false ; unlock my successor
The MCS queue-based algorithm (cont’d)
Local Spinning Mutual Exclusion
Using reads and writes
A local-spin tournament-tree algorithm
(Anderson, Yang, 1993)
Each node is
identified by
(level, number)
Level 2
Level 1
0
1
Level 0 0
Processes 0
0
1
1
2
2
3
4
3
5
6
7
O(log n) RMR complexity for both DSM and CC systems
This is optimal (Attiya, Hendler, woelfel, STOC 2008)
Uses O(n log n) registers
A local-spin tournament-tree algorithm (cont’d)
Shared:
- Per each node, v, there are 3 registers:
name[level, 2node], name[level, 2node+1] initially -1
turn[level, node]
- Per each level l and process i, a spin flag:
flag[ level, i ] initially 0
Local:
level, node, id
A local-spin tournament-tree algorithm (cont’d)
Program for process i
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
node:=i
For level = o to log n-1 do ;from leaf to root
node:= node/2 ;compute node in new level
id=node mod 2 ; compute ID for 2-process mutex algorithm (0 or 1)
name[level, 2node + id]:=i ;identify yourself
turn[level,node]:=i ;update the tie-breaker
flag[level, i]:=0 ;initialize my locally-accessible spin flag
rival:=name[level, 2node+1-id]
if ( (rival ≠ -1) and (turn[level, node] = i) ) ;if not sure I should precede rival
if (flag[level, rival] =0) If rival may get to wait at line 14
flag[level, rival]:=1 ;Release rival by letting it know I updated tie-breaker
await flag[level, i] ≠ 0 ;await until signaled by rival (so it updated tie-breaker)
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
if (turn[level,node]=i) ;if I lost
await flag[level,i]=2 ;wait till rival notifies me its my turn
id:=node ;move to the next level
EndFor
CS
for level=log n –1 downto 0 do ;begin exit code
id:= i/2level, node:= id/2 ;set node and id
name[level, 2node+id ]) :=-1 ;erase name
rival := turn[level,node] ;find who rival is (if there is one)
if rival ≠ i ;if there is a rival
23.
flag[level,rival] :=2 ;notify rival
© Copyright 2026 Paperzz