master-degree-notes/Concurrent Systems/notes/3.md

110 lines
1.9 KiB
Markdown
Raw Normal View History

2025-03-10 08:29:43 +01:00
### Hardware primitives
Atomic R/W registers provide quite a basic computational model.
We can strenghten the model by adding specialized HW primitives, that essentially perform in an atomic way the combination of some atomic instructions.
Usually, every operating system provides at least one specilized HW primitive.
##### Most common ones:
2025-03-10 08:34:43 +01:00
- **Test&set:** atomic read+write of a boolean register
- **Swap:** atomic read+write of a general register (generalization of the above)
- **Fetch&add:** atomic read+increase of an integer register
- **Compare&swap:** tests the value of a general register, returns a boolean (result of the comparison, true if it is the same).
#### Test&Set
```
Let X be a boolean register
X.test&set() :=
tmp <- X
X <- 1
return tmp
(the function is implemented in an atomic way by the hardware by suspending the interruptions!)
```
2025-03-10 08:44:43 +01:00
###### How do we use it for MUTEX?
2025-03-10 08:34:43 +01:00
```
2025-03-10 08:39:43 +01:00
lock() :=
wait X.test&set() = 0
return
unlock() :=
X <- 0
return
```
#### Swap
```
X general register
X.swap(v) :=
tmp <- X
X <- v
return tmp
2025-03-10 08:44:43 +01:00
```
###### How do we use it for MUTEX?
```
lock() :=
wait X.swap(1) = 0
return
unlock() :=
X <- 0
return
```
#### Compare&swap
```
X boolean register
X.compare&swap(old, new) :=
if X = old then
X <- new
return true
return false
```
###### How do we use it for MUTEX?
```
Initialize X at 0
lock() :=
wait X.compare&swap(0, 1) = true
return
unlock() :=
X <- 0
return
```
#### Fetch&add
Up to now, all solutions enjoy deadlock freedom, but allow for starvation. So let's use Round Robin to promote the liveness property!
Let X be an integer register; the Fetch&add primitive is implemented as follows:
```
X.fetch&add(v) :=
tmp <- X
X <- X+v
return tmp
```
2025-03-10 08:49:43 +01:00
###### How do we use it for MUTEX?
```
Initialize TICKET and NEXT at 0
lock() :=
my_ticket <- TICKET.fetch&add(1)
wait my_ticket = NEXT
return
unlock() :=
NEXT <- NEXT + 1
return
```
>[!info} It is bounded bypass with bound n-1