- empty : T
Class to represent 'reservations'
Reservations are the main method for reasoning about inter-thread behaviour.
Basic idea: Only threads with a certain reservation are allowed to do certain things. In many cases, some operation cannot be done atomically. Instead, a thread needs to do several steps. Using reservations, the thread can keep track about how many of those steps it has already accomplished. Other threads have no way to manipulate each other's reservation, only their own.
For reasoning, the reservations of all threads have to be taken into account. However, we want:
- The order of the other threads should not matter
- It should not matter if there are 10 other threads, or only one which achieved those reservations
As a consequence, we require an addition operator for reservations. Invariants used for reasoning may use both the shared state and the sum of all reservations, but not individual reservations. Each thread has to guarantee the invariant, but it only knows about its own reservation, i.e. it has a lower bound on the reservation, but nothing more. Therefore, it's actions are limited by the reservation it has already achieved on its own.
Example: #
-
There is one shared
Nat
variablex
-
Each thread performs the following three steps:
- generate a random variable
n : Nat
- increase
x
byn + 1
atomically - decrease
x
byn
atomically
- generate a random variable
-
We want to reason that - in the end -
x
is never zero.Solution: We introduce a
reservation : Nat
reservation which keeps track of how much we have increasedx
. Therefore, the have the invariant ∑reservation = x. Now, we can easily reason about the thread: -
Step 1: Generating the random number has no effect on the shared variable
-
Step 2: We increase
x
byn + 1
and assignreservation :=n + 1
. Since the reservations of the other threads have not changed, the invariant still holds -
Step 3: Since no other thread can affect our reservation, we still know that
reservation = n + 1
. Because of our invariant, we also knowx = ∑reservation ≥ reservation = n + 1
. Therefore, we can safely decrease bothx
andreservation
byn
and we still havex > 0
Instances
- State : Type
- Reservation : Type
- is_reservation : Mt.IsReservation Reservation
- validate : Reservation → State → Prop
Specification for a multithreading system
This specification specifies the context for threads but not the threads itself. Threads encode a specification in their type. Only threads with the same specification can be executed in parallel
Instances For
Equations
- Mt.instAddLowerBound = { add := Nat.max }
Equations
- Mt.Lock.is_locked _fun_discr = match _fun_discr with | Mt.Lock.Locked a => true | x => false
Equations
- Mt.Lock.is_locked_and_valid valid _fun_discr = match _fun_discr with | Mt.Lock.Locked s => valid s | x => False
Equations
- Mt.Lock.is_unlocked _fun_discr = match _fun_discr with | Mt.Lock.Unlocked => true | x => false
Equations
- Mt.Lock.add _fun_discr _fun_discr = match _fun_discr, _fun_discr with | Mt.Lock.Unlocked, a => a | a, Mt.Lock.Unlocked => a | x, x_1 => Mt.Lock.Invalid
Equations
- Mt.instIsReservationLock = Mt.IsReservation.mk Mt.Lock.Unlocked (_ : ∀ (a : Mt.Lock T), Mt.Lock.Unlocked + a = a)