vault backup: 2025-03-10 08:24:43
This commit is contained in:
parent
567655964f
commit
eeb4507fb4
5 changed files with 158 additions and 158 deletions
38
.obsidian/workspace.json
vendored
38
.obsidian/workspace.json
vendored
|
@ -7,32 +7,32 @@
|
||||||
"id": "126da1a2d2b29212",
|
"id": "126da1a2d2b29212",
|
||||||
"type": "tabs",
|
"type": "tabs",
|
||||||
"children": [
|
"children": [
|
||||||
{
|
|
||||||
"id": "802d9ec58484849d",
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "145551a957195f29",
|
"id": "145551a957195f29",
|
||||||
"type": "leaf",
|
"type": "leaf",
|
||||||
"state": {
|
"state": {
|
||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
"file": "Concurrent Systems/notes/Lezione2.md",
|
"file": "Concurrent Systems/notes/2 - Fast mutex by Lamport.md",
|
||||||
"mode": "source",
|
"mode": "source",
|
||||||
"source": false
|
"source": false
|
||||||
},
|
},
|
||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "Lezione2"
|
"title": "2 - Fast mutex by Lamport"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "fd57e934213e31db",
|
||||||
|
"type": "leaf",
|
||||||
|
"state": {
|
||||||
|
"type": "markdown",
|
||||||
|
"state": {
|
||||||
|
"file": "Concurrent Systems/notes/1 - CS Basics.md",
|
||||||
|
"mode": "source",
|
||||||
|
"source": false
|
||||||
|
},
|
||||||
|
"icon": "lucide-file",
|
||||||
|
"title": "1 - CS Basics"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -208,11 +208,12 @@
|
||||||
"companion:Toggle completion": false
|
"companion:Toggle completion": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"active": "145551a957195f29",
|
"active": "fd57e934213e31db",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
|
"Concurrent Systems/notes/2b - Round Robin algorithm.md",
|
||||||
|
"Concurrent Systems/notes/2 - Fast mutex by Lamport.md",
|
||||||
"Concurrent Systems/notes/1b - Peterson algorithm.md",
|
"Concurrent Systems/notes/1b - Peterson algorithm.md",
|
||||||
"Concurrent Systems/notes/1 - CS Basics.md",
|
"Concurrent Systems/notes/1 - CS Basics.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",
|
||||||
|
@ -255,7 +256,6 @@
|
||||||
"Biometric Systems/notes/4. Face detection.md",
|
"Biometric Systems/notes/4. Face detection.md",
|
||||||
"Biometric Systems/frequently asked questions/BS_oral_questions_16022021.md",
|
"Biometric Systems/frequently asked questions/BS_oral_questions_16022021.md",
|
||||||
"Biometric Systems/notes/12. Iris recognition.md",
|
"Biometric Systems/notes/12. Iris recognition.md",
|
||||||
"Biometric Systems/notes/11. Fingerprints.md",
|
|
||||||
"Senza nome.canvas"
|
"Senza nome.canvas"
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -137,3 +137,11 @@ It satisfies MUTEX and starvation freedom. It does not satisfy bounded bypass:
|
||||||
- but the sleep can be arbitrary long and in the meanwhile the other two processes may have entered an unbounded number of CSs
|
- 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.
|
Easy to generalize to k-MUTEX.
|
||||||
|
|
||||||
|
Peterson's algorithm cost $O(n^2)$
|
||||||
|
A first way to reduce this cost is by using a tournament of MUTEX between pairs of processes:
|
||||||
|
![[Pasted image 20250304082459.png|350]]
|
||||||
|
|
||||||
|
Of course this is a binary tree, and the height of a binary tree is logaritmic to the number of leaves. A process then wins after $\lceil \log_{2}n \rceil$ competitions $\to O(\log n)$ cost.
|
||||||
|
|
||||||
|
But we can do better. Let's see an idea of a constant-time algorithm.
|
77
Concurrent Systems/notes/2 - Fast mutex by Lamport.md
Normal file
77
Concurrent Systems/notes/2 - Fast mutex by Lamport.md
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
Initial idea:
|
||||||
|
```
|
||||||
|
Initialize Y at ⊥, X at any value (e.g., 0)
|
||||||
|
|
||||||
|
lock(i) :=
|
||||||
|
x <- i
|
||||||
|
if Y != ⊥ then FAIL
|
||||||
|
else Y <- i
|
||||||
|
if X = i then return
|
||||||
|
else FAIL
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
Y <- ⊥
|
||||||
|
return
|
||||||
|
```
|
||||||
|
|
||||||
|
Problems:
|
||||||
|
- we don't want the FAIL
|
||||||
|
- it is possible to have an execution where nobody accesses its CS, if repeated forever it entails a deadlock
|
||||||
|
|
||||||
|
```
|
||||||
|
Initialize Y at ⊥, X at any value (e.g., 0)
|
||||||
|
|
||||||
|
|
||||||
|
lock(i) :=
|
||||||
|
* FLAG[i] <- up
|
||||||
|
X <- i
|
||||||
|
if Y ≠ ⊥ then
|
||||||
|
FLAG[i] <- down
|
||||||
|
wait Y = ⊥
|
||||||
|
goto *
|
||||||
|
else Y <- i
|
||||||
|
|
||||||
|
if X = i then return
|
||||||
|
else FLAG[i] <- down
|
||||||
|
|
||||||
|
∀j.wait FLAG[j] = down
|
||||||
|
|
||||||
|
if Y = i then return
|
||||||
|
else wait Y = ⊥
|
||||||
|
|
||||||
|
goto *
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
Y <- ⊥
|
||||||
|
FLAG[i] <- down
|
||||||
|
return
|
||||||
|
```
|
||||||
|
|
||||||
|
##### MUTEX proof
|
||||||
|
How can pi enter its CS?
|
||||||
|
![[Pasted image 20250304084537.png]]
|
||||||
|
|
||||||
|
![[Pasted image 20250304084901.png]]
|
||||||
|
(*must finished before nel senso che $p_i$ deve aspettare $p_j$*)
|
||||||
|
##### Deadlock freedom
|
||||||
|
Let $p_i$ invoke lock
|
||||||
|
- If it eventually wins -> √
|
||||||
|
- If it is blocked forever, where can it be blocked?
|
||||||
|
1. In the second wait Y = ⊥
|
||||||
|
- in this case, it read a value in Y different from i
|
||||||
|
- there is a $p_h$ that wrote Y after $p_i$
|
||||||
|
- let us consider the last of such $p_h \to$ it will eventually win
|
||||||
|
2. In the ∀j.wait FLAG[j] = down
|
||||||
|
- this wait cannot block a process forever
|
||||||
|
- if $pj$ doesn't lock, it flag is down
|
||||||
|
- if $pj$ doesn't find Y at ⊥, it puts its flag down
|
||||||
|
- if pj doesn't find X at j, it puts its flag down, otherwise pj enters its CS and eventually unlocks (flag down)
|
||||||
|
- 3. In the first wait Y = ⊥
|
||||||
|
- since pj read a value different from ⊥, there is at least one pk that wrote Y before (but has not yet unlocked)
|
||||||
|
- if $p_k$ eventually enters its CS -> ok, otherwise it must be blocked forever as well. Where?
|
||||||
|
- In the second wait Y = ⊥: but then there exists a $p_h$ that eventually enters its CS -> good
|
||||||
|
- In the ∀j.wait FLAG[j]=down: this wait cannot block a process forever
|
||||||
|
|
||||||
|
![[Pasted image 20250304090219.png]]
|
||||||
|
|
||||||
|
esercizio: prova che NON soddisfa starvation freedom
|
53
Concurrent Systems/notes/2b - Round Robin algorithm.md
Normal file
53
Concurrent Systems/notes/2b - Round Robin algorithm.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#### From deadlock freedom to bounded bypass
|
||||||
|
-> Round Robin algorithm
|
||||||
|
|
||||||
|
Let DLF be any deadlock free protocol for MUTEX. Let's see how we can make it satisfy bounded bypass:
|
||||||
|
|
||||||
|
```
|
||||||
|
lock(i) :=
|
||||||
|
FLAG[i] <- up
|
||||||
|
wait (TURN = i OR FLAG[TURN] = down)
|
||||||
|
DLF.lock(i)
|
||||||
|
return
|
||||||
|
|
||||||
|
unlock(i) :=
|
||||||
|
FLAG[i] <- down
|
||||||
|
if FLAG[TURN] = down then
|
||||||
|
TURN <- (TURN + 1) mod n
|
||||||
|
DLF.unlock(i)
|
||||||
|
return
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
###### Is it deadlock free?
|
||||||
|
Since DLF is deadlock free, it is sufficient to prove that at least one process invokes DLF.lock.
|
||||||
|
If TURN = k and $p_k$ invoked lock, then it finds TURN = k and exits its wait.
|
||||||
|
Otherwise, any other process will find `FLAG[TURN] = down` and exits from its wait.
|
||||||
|
|
||||||
|
**Lemma 1:** if TURN = i and `FLAG[i] = up` then $p_i$ enters the CS in at most n-1 iterations
|
||||||
|
|
||||||
|
Observation 1: TURN changes only when FLAG[i] is down (after pi has completed its CS)
|
||||||
|
|
||||||
|
Observation 2: FLAG[i] = up -> either pi is in its CS or pi is competing for its CS -> it eventually invokes (if not already) DLF.lock
|
||||||
|
|
||||||
|
Observation 3: if $p_j$ invokes lock after that FLAG[i] is set, $p_j$ blocks in its wait
|
||||||
|
|
||||||
|
Let Y be the set of processes competing for the CS (suspended on the DLF.lock)
|
||||||
|
- because of Observation 2, $i \in Y$
|
||||||
|
- because of Observation 3, once FLAG[i] is set, Y cannot grow anymore
|
||||||
|
- because DLF is deadlock free, eventually one $p_{y} \in Y$ wins if $y = i$.
|
||||||
|
- if $y = i$ we are done
|
||||||
|
- otherwise, Y shrinks by one. And because of Observation 1, TURN and FLAG[TURN] don't change, so $p_y$ cannot enter Y again.
|
||||||
|
- Iterating this reasoning we can see that $p_i$ will eventually win, and the worst case is when is the last winner.
|
||||||
|
|
||||||
|
**Lemma 2:** If FLAG[i] = up, then TURN is set to i in at most $(n-1)^2$ iterations.
|
||||||
|
|
||||||
|
If TURN=i when FLAG[i] is set, done
|
||||||
|
By Deadlock freedom of RR, at least one process eventually unlocks
|
||||||
|
- If FLAG[TURN] = down, then TURN is increased. Otherwise, by Lemam 1, $p_{TURN}$ wins in at most n-1 iterations and increases TURN.
|
||||||
|
- If now TURN = i then we are done. Otherwise, we repeat this reasoning.
|
||||||
|
|
||||||
|
The worst case is when TURN = *i+1* mod n when FLAG[i] is set.
|
||||||
|
|
||||||
|
![[Pasted image 20250304093223.png]]
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
Peterson's algorithm cost $O(n^2)$
|
|
||||||
A first way to reduce this cost is by using a tournament of MUTEX between pairs of processes:
|
|
||||||
![[Pasted image 20250304082459.png|350]]
|
|
||||||
|
|
||||||
Of course this is a binary tree, and the height of a binary tree is logaritmic to the number of leaves. A process then wins after $\lceil \log_{2}n \rceil$ competitions $\to O(\log n)$ cost.
|
|
||||||
|
|
||||||
But we can do better. Let's see an idea of a constant-time algorithm.
|
|
||||||
|
|
||||||
```
|
|
||||||
Initialize Y at ⊥, X at any value (e.g., 0)
|
|
||||||
|
|
||||||
lock(i) :=
|
|
||||||
x <- i
|
|
||||||
if Y != ⊥ then FAIL
|
|
||||||
else Y <- i
|
|
||||||
if X = i then return
|
|
||||||
else FAIL
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
Y <- ⊥
|
|
||||||
return
|
|
||||||
```
|
|
||||||
|
|
||||||
Problems:
|
|
||||||
- we don't want the FAIL
|
|
||||||
- it is possible to have an execution where nobody accesses its CS, if repeated forever it entails a deadlock
|
|
||||||
|
|
||||||
```
|
|
||||||
Initialize Y at ⊥, X at any value (e.g., 0)
|
|
||||||
|
|
||||||
|
|
||||||
lock(i) :=
|
|
||||||
* FLAG[i] <- up
|
|
||||||
X <- i
|
|
||||||
if Y ≠ ⊥ then
|
|
||||||
FLAG[i] <- down
|
|
||||||
wait Y = ⊥
|
|
||||||
goto *
|
|
||||||
else Y <- i
|
|
||||||
|
|
||||||
if X = i then return
|
|
||||||
else FLAG[i] <- down
|
|
||||||
|
|
||||||
∀j.wait FLAG[j] = down
|
|
||||||
|
|
||||||
if Y = i then return
|
|
||||||
else wait Y = ⊥
|
|
||||||
|
|
||||||
goto *
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
Y <- ⊥
|
|
||||||
FLAG[i] <- down
|
|
||||||
return
|
|
||||||
```
|
|
||||||
|
|
||||||
##### MUTEX proof
|
|
||||||
How can pi enter its CS?
|
|
||||||
![[Pasted image 20250304084537.png]]
|
|
||||||
|
|
||||||
![[Pasted image 20250304084901.png]]
|
|
||||||
(*must finished before nel senso che $p_i$ deve aspettare $p_j$*)
|
|
||||||
##### Deadlock freedom
|
|
||||||
Let $p_i$ invoke lock
|
|
||||||
- If it eventually wins -> √
|
|
||||||
- If it is blocked forever, where can it be blocked?
|
|
||||||
1. In the second wait Y = ⊥
|
|
||||||
- in this case, it read a value in Y different from i
|
|
||||||
- there is a $p_h$ that wrote Y after $p_i$
|
|
||||||
- let us consider the last of such $p_h \to$ it will eventually win
|
|
||||||
2. In the ∀j.wait FLAG[j] = down
|
|
||||||
- this wait cannot block a process forever
|
|
||||||
- if $pj$ doesn't lock, it flag is down
|
|
||||||
- if $pj$ doesn't find Y at ⊥, it puts its flag down
|
|
||||||
- if pj doesn't find X at j, it puts its flag down, otherwise pj enters its CS and eventually unlocks (flag down)
|
|
||||||
- 3. In the first wait Y = ⊥
|
|
||||||
- since pj read a value different from ⊥, there is at least one pk that wrote Y before (but has not yet unlocked)
|
|
||||||
- if $p_k$ eventually enters its CS -> ok, otherwise it must be blocked forever as well. Where?
|
|
||||||
- In the second wait Y = ⊥: but then there exists a $p_h$ that eventually enters its CS -> good
|
|
||||||
- In the ∀j.wait FLAG[j]=down: this wait cannot block a process forever
|
|
||||||
|
|
||||||
![[Pasted image 20250304090219.png]]
|
|
||||||
|
|
||||||
esercizio: prova che NON soddisfa starvation freedom
|
|
||||||
|
|
||||||
#### From deadlock freedom to bounded bypass
|
|
||||||
-> Round Robin algorithm
|
|
||||||
|
|
||||||
Let DLF be any deadlock free protocol for MUTEX. Let's see how we can make it satisfy bounded bypass:
|
|
||||||
|
|
||||||
```
|
|
||||||
lock(i) :=
|
|
||||||
FLAG[i] <- up
|
|
||||||
wait (TURN = i OR FLAG[TURN] = down)
|
|
||||||
DLF.lock(i)
|
|
||||||
return
|
|
||||||
|
|
||||||
unlock(i) :=
|
|
||||||
FLAG[i] <- down
|
|
||||||
if FLAG[TURN] = down then
|
|
||||||
TURN <- (TURN + 1) mod n
|
|
||||||
DLF.unlock(i)
|
|
||||||
return
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
###### Is it deadlock free?
|
|
||||||
Since DLF is deadlock free, it is sufficient to prove that at least one process invokes DLF.lock.
|
|
||||||
If TURN = k and $p_k$ invoked lock, then it finds TURN = k and exits its wait.
|
|
||||||
Otherwise, any other process will find `FLAG[TURN] = down` and exits from its wait.
|
|
||||||
|
|
||||||
**Lemma 1:** if TURN = i and `FLAG[i] = up` then $p_i$ enters the CS in at most n-1 iterations
|
|
||||||
|
|
||||||
Observation 1: TURN changes only when FLAG[i] is down (after pi has completed its CS)
|
|
||||||
|
|
||||||
Observation 2: FLAG[i] = up -> either pi is in its CS or pi is competing for its CS -> it eventually invokes (if not already) DLF.lock
|
|
||||||
|
|
||||||
Observation 3: if $p_j$ invokes lock after that FLAG[i] is set, $p_j$ blocks in its wait
|
|
||||||
|
|
||||||
Let Y be the set of processes competing for the CS (suspended on the DLF.lock)
|
|
||||||
- because of Observation 2, $i \in Y$
|
|
||||||
- because of Observation 3, once FLAG[i] is set, Y cannot grow anymore
|
|
||||||
- because DLF is deadlock free, eventually one $p_{y} \in Y$ wins if $y = i$.
|
|
||||||
- if $y = i$ we are done
|
|
||||||
- otherwise, Y shrinks by one. And because of Observation 1, TURN and FLAG[TURN] don't change, so $p_y$ cannot enter Y again.
|
|
||||||
- Iterating this reasoning we can see that $p_i$ will eventually win, and the worst case is when is the last winner.
|
|
||||||
|
|
||||||
**Lemma 2:** If FLAG[i] = up, then TURN is set to i in at most $(n-1)^2$ iterations.
|
|
||||||
|
|
||||||
If TURN=i when FLAG[i] is set, done
|
|
||||||
By Deadlock freedom of RR, at least one process eventually unlocks
|
|
||||||
- If FLAG[TURN] = down, then TURN is increased. Otherwise, by Lemam 1, $p_{TURN}$ wins in at most n-1 iterations and increases TURN.
|
|
||||||
- If now TURN = i then we are done. Otherwise, we repeat this reasoning.
|
|
||||||
|
|
||||||
The worst case is when TURN = *i+1* mod n when FLAG[i] is set.
|
|
||||||
|
|
||||||
![[Pasted image 20250304093223.png]]
|
|
||||||
|
|
Loading…
Reference in a new issue