vault backup: 2025-03-08 18:06:57
This commit is contained in:
parent
db7262759e
commit
3645c0f6f4
3 changed files with 155 additions and 140 deletions
22
.obsidian/workspace.json
vendored
22
.obsidian/workspace.json
vendored
|
@ -20,8 +20,23 @@
|
||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "1 - CS Basics"
|
"title": "1 - CS Basics"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "145551a957195f29",
|
||||||
|
"type": "leaf",
|
||||||
|
"state": {
|
||||||
|
"type": "markdown",
|
||||||
|
"state": {
|
||||||
|
"file": "Concurrent Systems/notes/1b - Peterson algorithm.md",
|
||||||
|
"mode": "source",
|
||||||
|
"source": false
|
||||||
|
},
|
||||||
|
"icon": "lucide-file",
|
||||||
|
"title": "1b - Peterson algorithm"
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
],
|
||||||
|
"currentTab": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"direction": "vertical"
|
"direction": "vertical"
|
||||||
|
@ -193,10 +208,11 @@
|
||||||
"companion:Toggle completion": false
|
"companion:Toggle completion": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": "802d9ec58484849d",
|
"active": "145551a957195f29",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
"Concurrent Systems/notes/Lezione2.md",
|
|
||||||
"Concurrent Systems/notes/1 - CS Basics.md",
|
"Concurrent Systems/notes/1 - CS Basics.md",
|
||||||
|
"Concurrent Systems/notes/1b - Peterson algorithm.md",
|
||||||
|
"Concurrent Systems/notes/Lezione2.md",
|
||||||
"HCIW/slides/Interface and Interaction for IoT.pdf",
|
"HCIW/slides/Interface and Interaction for IoT.pdf",
|
||||||
"Pasted image 20250305182542.png",
|
"Pasted image 20250305182542.png",
|
||||||
"HCIW/notes/3 - Beacons.md",
|
"HCIW/notes/3 - Beacons.md",
|
||||||
|
|
|
@ -114,139 +114,3 @@ Atomic R/W registers are storage units that can be accessed through two operatio
|
||||||
- may be located in any point between its starting and ending time
|
- may be located in any point between its starting and ending time
|
||||||
- does not happen together with any other operation ($t$ is injective)
|
- does not happen together with any other operation ($t$ is injective)
|
||||||
2. Every READ returns the closest preceding value written in the register, or the initial value (if no WRITE has occurred).
|
2. Every READ returns the closest preceding value written in the register, or the initial value (if no WRITE has occurred).
|
||||||
|
|
||||||
### Peterson algorithm (for two processes)
|
|
||||||
Let's try to enforce MUTEX with just 2 processes.
|
|
||||||
|
|
||||||
##### 1st attempt:
|
|
||||||
```
|
|
||||||
lock(i) :=
|
|
||||||
AFTER_YOU <- i
|
|
||||||
wait AFTER_YOU != i
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
return
|
|
||||||
```
|
|
||||||
This protocol satisfies MUTEX, but suffers from deadlock (if one process never locks).
|
|
||||||
|
|
||||||
##### 2nd attempt:
|
|
||||||
```
|
|
||||||
Initialize FLAG[0] and FLAG[1] to down
|
|
||||||
lock(i) :=
|
|
||||||
FLAG[i] <- up
|
|
||||||
wait FLAG[1-i] = down
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
FLAG[i] <- down
|
|
||||||
return
|
|
||||||
```
|
|
||||||
Still suffers from deadlock if both processes simultaneously raise their flag.
|
|
||||||
|
|
||||||
##### Correct solution:
|
|
||||||
```
|
|
||||||
Initialize FLAG[0] and FLAG[1] to down
|
|
||||||
lock(i) :=
|
|
||||||
FLAG[i] <- up
|
|
||||||
AFTER_YOU <- i
|
|
||||||
wait FLAG[1-i] = down OR AFTER_YOU != i
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
FLAG[i] <- down
|
|
||||||
return
|
|
||||||
```
|
|
||||||
|
|
||||||
**Features:**
|
|
||||||
- it satisfies MUTEX
|
|
||||||
- it satisfies bounded bypass, with bound = 1
|
|
||||||
- it requires 2 one-bit SRSW registers (the flags and 1 one-bit MRMW registers (AFTER_YOU)
|
|
||||||
- Each lock-unlock requires 5 accesses to the registers (4 for lock and 1 for unlock)
|
|
||||||
|
|
||||||
##### MUTEX proof
|
|
||||||
Assume p0 and p1 are simultaneously in the CS.
|
|
||||||
|
|
||||||
How has p0 entered its CS?
|
|
||||||
a) `FLAG[1] = down`, this is possible only with the following interleaving:
|
|
||||||
![[Pasted image 20250303100721.png]]
|
|
||||||
|
|
||||||
b) `AFTER_YOU = 1`, this is possible only with the following interleaving:
|
|
||||||
![[Pasted image 20250303100953.png]]
|
|
||||||
|
|
||||||
##### Bounded Bypass proof (with bound = 1)
|
|
||||||
- If the wait condition is true, then it wins (and waits 0).
|
|
||||||
|
|
||||||
- Otherwise, it must be that `FLAG[1] = UP` **AND** `AFTER_YOU = 0` (quindi p1 ha invocato il lock e p0 dovrà aspettare).
|
|
||||||
|
|
||||||
- If p1 never locks anymore then p0 will eventually read `F[1]` and win (waiting 1).
|
|
||||||
|
|
||||||
- It is possible tho that p1 locks again:
|
|
||||||
- if p0 reads `F[1]` before p1 locks, then p0 wins (waiting 1)
|
|
||||||
- otherwise p1 sets A_Y to 1 and suspends in its wait (`F[0] = up AND A_Y = 1`), p0 will eventually read `F[1]` and win (waiting 1).
|
|
||||||
|
|
||||||
### Peterson algorithm ($n$ processes)
|
|
||||||
- FLAG now has $n$ levels (from 0 to n-1)
|
|
||||||
- level 0 means down
|
|
||||||
- level >0 means involved in the lock
|
|
||||||
- Every level has its own AFTER_YOU
|
|
||||||
|
|
||||||
```
|
|
||||||
Initialize FLAG[i] to 0, for all i
|
|
||||||
|
|
||||||
lock(i) :=
|
|
||||||
for lev = 1 to n-1 do
|
|
||||||
FLAG[i] <- lev
|
|
||||||
AFTER_YOU[lev] <- i
|
|
||||||
wait (∀k!=i, FLAG[k] < lev
|
|
||||||
OR AFTER_YOU[lev] != i)
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
FLAG[i] <- 0
|
|
||||||
return
|
|
||||||
```
|
|
||||||
We say that pi is at level h when it exits from the h-th wait -> a process at level h is at any level <= h
|
|
||||||
|
|
||||||
##### MUTEX proof
|
|
||||||
Lemma: for every $ℓ \in \{0,\dots,n-1\}$ , at most n-ℓ processes are at level ℓ, this implies MUTEX by taking ℓ = n-1
|
|
||||||
|
|
||||||
Proof by induction on ℓ
|
|
||||||
|
|
||||||
Base (ℓ=0): trivial
|
|
||||||
|
|
||||||
Induction (true for ℓ, to be proved for ℓ+1):
|
|
||||||
- p at level ℓ can increase its level by writing its FLAG at ℓ+1 and its index in $A_Y[ℓ+1]$
|
|
||||||
- let $p_x$ be the last one that writes `A_Y[ℓ+1]`, so `A_Y[ℓ+1]=x`
|
|
||||||
- for $p_x$ to pass at level ℓ+1, it must be that $∀k≠x. F[k] < ℓ+1$, then $p_x$ is the only proc at level ℓ+1 and the thesis holds, since 1<=n-ℓ-1
|
|
||||||
- otherwise, $p_x$ is blocked in the wait and so we have at most n-ℓ-1 processes at level ℓ+1: those at level ℓ, that by induction are at most n-ℓ, except for px that is blocked in its wait.
|
|
||||||
|
|
||||||
##### Starvation freedom proof
|
|
||||||
**Lemma:** every process at level ℓ ($\leq n-1$) eventually wins $\to$ starvation freedom holds by taking $ℓ=0$.
|
|
||||||
|
|
||||||
Reverse induction on ℓ
|
|
||||||
Base ($ℓ=n-1$): trivial
|
|
||||||
|
|
||||||
Induction (true for ℓ+1, to be proved for ℓ):
|
|
||||||
- Assume a $p_x$ blocked at level ℓ (aka blocked in its ℓ+1-th wait) $\to \exists k\neq x, F[k]\geqℓ+1 \land A\_Y[ℓ+1]=x$
|
|
||||||
|
|
||||||
- If some $p_{y}$ will eventually set $A\_Y[ℓ+1]$ to $y$, then $p_x$ will eventually exit from its wait and pass to level ℓ+1
|
|
||||||
|
|
||||||
- Otherwise, let $G = \{p_{i}: F[i] \geq ℓ+1\}$ and $L=\{p_{i}:F[i]<ℓ+1\}$
|
|
||||||
- if $p \in L$, it will never enter its ℓ+1-th loop (as it would write $A_Y[ℓ+1]$ and it will unblock $p_x$, but we are assuming that it is blocked)
|
|
||||||
- all $p \in G$ will eventually win (by induction) and move to L
|
|
||||||
- $\to$ eventually, $p_{x}$ will be the only one in its ℓ+1-th loop, with all the other processes at level <ℓ+1
|
|
||||||
- $\to$ $p_{x}$ will eventually pass to level ℓ+1 and win (by induction)
|
|
||||||
|
|
||||||
|
|
||||||
##### Peterson algorithm cost
|
|
||||||
- $n$ MRSW registers of $\lceil \log_{2} n\rceil$ bits (FLAG)
|
|
||||||
- $n-1$ MRMW registers of $\lceil \log_{2}n \rceil$ bits (AFTER_YOU)
|
|
||||||
- $(n-1)\times(n+2)$ accesses for locking and 1 access for unlocking
|
|
||||||
|
|
||||||
It satisfies MUTEX and starvation freedom. It does not satisfy bounded bypass:
|
|
||||||
- consider 3 processes, one sleeping in its first wait, the others alternating in the CS
|
|
||||||
- when the first process wakes up, it can pass to level 2 and eventually win
|
|
||||||
- but the sleep can be arbitrary long and in the meanwhile the other two processes may have entered an unbounded number of CSs
|
|
||||||
|
|
||||||
Easy to generalize to k-MUTEX.
|
|
135
Concurrent Systems/notes/1b - Peterson algorithm.md
Normal file
135
Concurrent Systems/notes/1b - Peterson algorithm.md
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
### Peterson algorithm (for two processes)
|
||||||
|
Let's try to enforce MUTEX with just 2 processes.
|
||||||
|
|
||||||
|
##### 1st attempt:
|
||||||
|
```
|
||||||
|
lock(i) :=
|
||||||
|
AFTER_YOU <- i
|
||||||
|
wait AFTER_YOU != i
|
||||||
|
return
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
return
|
||||||
|
```
|
||||||
|
This protocol satisfies MUTEX, but suffers from deadlock (if one process never locks).
|
||||||
|
|
||||||
|
##### 2nd attempt:
|
||||||
|
```
|
||||||
|
Initialize FLAG[0] and FLAG[1] to down
|
||||||
|
lock(i) :=
|
||||||
|
FLAG[i] <- up
|
||||||
|
wait FLAG[1-i] = down
|
||||||
|
return
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
FLAG[i] <- down
|
||||||
|
return
|
||||||
|
```
|
||||||
|
Still suffers from deadlock if both processes simultaneously raise their flag.
|
||||||
|
|
||||||
|
##### Correct solution:
|
||||||
|
```
|
||||||
|
Initialize FLAG[0] and FLAG[1] to down
|
||||||
|
lock(i) :=
|
||||||
|
FLAG[i] <- up
|
||||||
|
AFTER_YOU <- i
|
||||||
|
wait FLAG[1-i] = down OR AFTER_YOU != i
|
||||||
|
return
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
FLAG[i] <- down
|
||||||
|
return
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- it satisfies MUTEX
|
||||||
|
- it satisfies bounded bypass, with bound = 1
|
||||||
|
- it requires 2 one-bit SRSW registers (the flags and 1 one-bit MRMW registers (AFTER_YOU)
|
||||||
|
- Each lock-unlock requires 5 accesses to the registers (4 for lock and 1 for unlock)
|
||||||
|
|
||||||
|
##### MUTEX proof
|
||||||
|
Assume p0 and p1 are simultaneously in the CS.
|
||||||
|
|
||||||
|
How has p0 entered its CS?
|
||||||
|
a) `FLAG[1] = down`, this is possible only with the following interleaving:
|
||||||
|
![[Pasted image 20250303100721.png]]
|
||||||
|
|
||||||
|
b) `AFTER_YOU = 1`, this is possible only with the following interleaving:
|
||||||
|
![[Pasted image 20250303100953.png]]
|
||||||
|
|
||||||
|
##### Bounded Bypass proof (with bound = 1)
|
||||||
|
- If the wait condition is true, then it wins (and waits 0).
|
||||||
|
|
||||||
|
- Otherwise, it must be that `FLAG[1] = UP` **AND** `AFTER_YOU = 0` (quindi p1 ha invocato il lock e p0 dovrà aspettare).
|
||||||
|
|
||||||
|
- If p1 never locks anymore then p0 will eventually read `F[1]` and win (waiting 1).
|
||||||
|
|
||||||
|
- It is possible tho that p1 locks again:
|
||||||
|
- if p0 reads `F[1]` before p1 locks, then p0 wins (waiting 1)
|
||||||
|
- otherwise p1 sets A_Y to 1 and suspends in its wait (`F[0] = up AND A_Y = 1`), p0 will eventually read `F[1]` and win (waiting 1).
|
||||||
|
|
||||||
|
### Peterson algorithm ($n$ processes)
|
||||||
|
- FLAG now has $n$ levels (from 0 to n-1)
|
||||||
|
- level 0 means down
|
||||||
|
- level >0 means involved in the lock
|
||||||
|
- Every level has its own AFTER_YOU
|
||||||
|
|
||||||
|
```
|
||||||
|
Initialize FLAG[i] to 0, for all i
|
||||||
|
|
||||||
|
lock(i) :=
|
||||||
|
for lev = 1 to n-1 do
|
||||||
|
FLAG[i] <- lev
|
||||||
|
AFTER_YOU[lev] <- i
|
||||||
|
wait (∀k!=i, FLAG[k] < lev
|
||||||
|
OR AFTER_YOU[lev] != i)
|
||||||
|
return
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
FLAG[i] <- 0
|
||||||
|
return
|
||||||
|
```
|
||||||
|
We say that pi is at level h when it exits from the h-th wait -> a process at level h is at any level <= h
|
||||||
|
|
||||||
|
##### MUTEX proof
|
||||||
|
Lemma: for every $ℓ \in \{0,\dots,n-1\}$ , at most n-ℓ processes are at level ℓ, this implies MUTEX by taking ℓ = n-1
|
||||||
|
|
||||||
|
Proof by induction on ℓ
|
||||||
|
|
||||||
|
Base (ℓ=0): trivial
|
||||||
|
|
||||||
|
Induction (true for ℓ, to be proved for ℓ+1):
|
||||||
|
- p at level ℓ can increase its level by writing its FLAG at ℓ+1 and its index in $A_Y[ℓ+1]$
|
||||||
|
- let $p_x$ be the last one that writes `A_Y[ℓ+1]`, so `A_Y[ℓ+1]=x`
|
||||||
|
- for $p_x$ to pass at level ℓ+1, it must be that $∀k≠x. F[k] < ℓ+1$, then $p_x$ is the only proc at level ℓ+1 and the thesis holds, since 1<=n-ℓ-1
|
||||||
|
- otherwise, $p_x$ is blocked in the wait and so we have at most n-ℓ-1 processes at level ℓ+1: those at level ℓ, that by induction are at most n-ℓ, except for px that is blocked in its wait.
|
||||||
|
|
||||||
|
##### Starvation freedom proof
|
||||||
|
**Lemma:** every process at level ℓ ($\leq n-1$) eventually wins $\to$ starvation freedom holds by taking $ℓ=0$.
|
||||||
|
|
||||||
|
Reverse induction on ℓ
|
||||||
|
Base ($ℓ=n-1$): trivial
|
||||||
|
|
||||||
|
Induction (true for ℓ+1, to be proved for ℓ):
|
||||||
|
- Assume a $p_x$ blocked at level ℓ (aka blocked in its ℓ+1-th wait) $\to \exists k\neq x, F[k]\geqℓ+1 \land A\_Y[ℓ+1]=x$
|
||||||
|
|
||||||
|
- If some $p_{y}$ will eventually set $A\_Y[ℓ+1]$ to $y$, then $p_x$ will eventually exit from its wait and pass to level ℓ+1
|
||||||
|
|
||||||
|
- Otherwise, let $G = \{p_{i}: F[i] \geq ℓ+1\}$ and $L=\{p_{i}:F[i]<ℓ+1\}$
|
||||||
|
- if $p \in L$, it will never enter its ℓ+1-th loop (as it would write $A_Y[ℓ+1]$ and it will unblock $p_x$, but we are assuming that it is blocked)
|
||||||
|
- all $p \in G$ will eventually win (by induction) and move to L
|
||||||
|
- $\to$ eventually, $p_{x}$ will be the only one in its ℓ+1-th loop, with all the other processes at level <ℓ+1
|
||||||
|
- $\to$ $p_{x}$ will eventually pass to level ℓ+1 and win (by induction)
|
||||||
|
|
||||||
|
|
||||||
|
##### Peterson algorithm cost
|
||||||
|
- $n$ MRSW registers of $\lceil \log_{2} n\rceil$ bits (FLAG)
|
||||||
|
- $n-1$ MRMW registers of $\lceil \log_{2}n \rceil$ bits (AFTER_YOU)
|
||||||
|
- $(n-1)\times(n+2)$ accesses for locking and 1 access for unlocking
|
||||||
|
|
||||||
|
It satisfies MUTEX and starvation freedom. It does not satisfy bounded bypass:
|
||||||
|
- consider 3 processes, one sleeping in its first wait, the others alternating in the CS
|
||||||
|
- when the first process wakes up, it can pass to level 2 and eventually win
|
||||||
|
- but the sleep can be arbitrary long and in the meanwhile the other two processes may have entered an unbounded number of CSs
|
||||||
|
|
||||||
|
Easy to generalize to k-MUTEX.
|
Loading…
Reference in a new issue