vault backup: 2025-03-08 18:06:57

This commit is contained in:
Marco Realacci 2025-03-08 18:06:57 +01:00
parent db7262759e
commit 3645c0f6f4
3 changed files with 155 additions and 140 deletions

View file

@ -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",

View file

@ -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.

View 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.