### Aravind’s algorithm Problem with Lamport's "Bakery" algorithm: registers must be unbounded (every invocation of lock potentially increases the counter by 1 -> domain of the registers is all natural numbers!) For all processes, we have a FLAG and a STAGE (both binary MRSW) and a DATE (MRMW) register that ranges from 1 to 2n. ``` For all i, initialize FLAG[i] to down STAGE[i] to 0 DATE[i] to i lock(i) := FLAG[i] <- up repeat STAGE[i] <- 0 wait (foreach j != i, FLAG[j] = down OR DATE[i] < DATE[j]) STAGE[i] <- 1 until foreach j != i, STAGE[j] = 0 unlock(i) := tmp <- max_j{DATE[j]}+1 if tmp >= 2n then foreach j, DATE[j] <- j else DATE[i] <- tmp STAGE[i] <- 0 FLAG[i] <- down ``` #### MUTEX proof **Theorem:** if $p_i$ is in the CS, then $p_j$ cannot simultaneously be in the CS. *Proof:* by contradiction. Let's consider the execution of $p_i$ leading to its CS: ![[Pasted image 20250310172134.png]] **Corollary** (of the MUTEX proof)**:** DATE is never written concurrently. #### Bounded bypass proof **Lemma 1:** exactly after n CSs there is a reset of DATE. *Proof:* - the first CS leads $max_j{DATE[j]}$ to n+1 - the seconds CS leads ... to n+2 - ... - the n-th read leads ... to n+n = 2n -> RESET **Lemma 2:** there can be at most one reset of DATE during an invocation of a lock *Proof:* - let $p_i$ invoke lock, if no reset occurs, ok - otherwise, let us consider the moment in which a reset occurs - if pi is the next process that enters the CS, ok - Otherwise let $p_j$ be the process that enters; its next date is $n+1 > DATE[i]$ - $p_{j}$ cannot surpass $p_i$ again (before a RESET) - The worst case is then all processes perform lock together and $i = n$ (i am process n) - all $p_{1}\dots p_{n}$ surpass $p_{n}$ - then $p_n$ enters and it resets the DATE in its unlock - only 1 reset and it is the worst case! **Theorem:** the algorithm satisfies bounded bypass with bound $2n-2$. *Proof:* ![[Pasted image 20250310103703.png]] so by this, the very worst possible case is that my lock experiences that. It looks like I can experience at most $2n-1$ other critical sections, but it is even better, let's see: - $p_n$ invokes lock alone, completes its CS (the first after the reset) and its new DATE is n+1 - all processes invoke lock simultaneously - $p_{n}$ has to wait all other processes to complete their CSs - when $p_{n-1}$ completes its CS, its new DATE will be $n+(n-1)+1=2n$ -> RESET - now all $p_{1}\dots p_{n-1}$ invoke lock again and complete their CSs (after that $p_i$ completes its CS, now it has `DATE[i] <- n+i`, because as everyone invoked lock after the RESET, max date was `n`) - so $p_n$ has to wait n-1 CSs for the reset, and another n-1 CSs before entering again. **Literally the worst case is when the process is the first of the first round, and the last of the last round.** #### Improvement of Aravind’s algorithm ``` unlock(i) := ∀j≠i.if DATE[j] > DATE[i] then DATE[j] <- DATE[j]-1 DATE[i] <- n STAGE[i] <- 0 FLAG[i] <- down ``` Since the LOCK is like before, the revised protocol satisfies MUTEX. Furthermore, you can prove that it satisfies bounded bypass with bound n-1 -> EXERCISE! Let's remember ourselves how is the locking function defined: ``` lock(i) := FLAG[i] <- up repeat STAGE[i] <- 0 wait (foreach j != i, FLAG[j] = down OR DATE[i] < DATE[j]) STAGE[i] <- 1 until foreach j != i, STAGE[j] = 0 ```