Your solution for this assignment should terminate within 10 seconds (when running ./pan
). If they exceed the time limit, you will get partial credit. Please also note how long your solutions take to run as a comment if they do exceed the time limit.
The Peterson lock that we saw in class has two key flaws:
In this assignment, you’ll model a different lock–Anderson’s queue lock– which works for an arbitrary number of threads. It also provides a FIFO guarantee as well as mutual exclusion and starvation-freedom. The algorithm assumes that we have some hardware support: an atomic “get and increment” action that lets us atomically read, and then increment, an integer variable.
Suppose you have n
threads that can contend for access. The algorithm uses:
n
-cell array of booleans (to serve as flags);next
;mySlot
.Initially, only flags[0]
is true (the rest is false), and next = 0
.
If a process wants access, it first gets-and-increments next
, placing the
result into its local mySlot
variable. This gives it a unique index into
the flags array: mySlot
mod n
. It then waits until flags[mySlot % n]
is true. When it finishes, it sets its own flag to false and the next slot in the flag array
to true.
Note that byte
's range is 0-255. Thus, when 256 is assigned to next
, spin queuelock.pml
will show
Error: value (256->0 (8)) truncated in assignment
However, Spin’s output is misleading here: this actually a warning rather than an error. The simulation will continue running without any problem.
For more information, include pseudocode, see the “Spin Locks” slides (starting on slide 96) from Prof. Herlihy’s class.
The provided template has already set up most of this algorithm for you.
Please use the template (below). The variables for verification hint at one way to check the desired properties.
NTHREADS = 2
):
NTHREADS
to 3
and check the same properties. One will fail. Make
a one-line change to the template’s get_and_increment
macro that corrects the
issue, and document why this change is an acceptable abstraction decision.Hint: as mentioned above, Spin will faithfully model overflow in the next
variable. How does this
interact with the modulo arithmetic?
spin -a queuelock.pml
gcc -DBFS -DBITSTATE -o pan pan.c
./pan -i
./pan -m100000
mySlot
):
spin -t -p -l
// Adjust this to change the number of threads (N=2 at first)
#define NTHREADS 2
/////////////////////////////////////////////////////////////////////
// Promela has C-macro like inlines. These are not helper functions;
// they can't return anything. Invocations get replaced with the
// code inside at compile time.
// A d_step is an optimized "atomic" statement: these blocks cannot
// be interrupted by other processes, and thus simulate a
// hardware-provided get_and_increment action.
inline get_and_increment(VAR, RESULT) {
d_step {
RESULT = VAR;
VAR = VAR + 1;
}
}
/////////////////////////////////////////////////////////////////////
// first is true; rest false (this repeats for the size of NTHREADS)
bool flags[NTHREADS];
byte next = 0; // the thread that gets slot 0 goes first
// Variables for verification.
byte num_in_crit = 0; // number of threads in the critical section
byte whichSlotExpectedNext = 0; // Hint: used to assert that the next slot is really used next
/////////////////////////////////////////////////////////////////////
// Processes contending for the lock. Start with N of them!
active [NTHREADS] proctype a_process()
{
// Allocate a different mySlot for each a_process instance. Doing this, instead of
// making a global array of length NTHREADS tells Spin that each mySlot can only be
// accessed by its local thread, which speeds up verification.
byte mySlot;
do
::
get_and_increment(next,mySlot); // grab a slot
flags[mySlot % NTHREADS]; // block until my slot is true
flags[mySlot % NTHREADS] = false; // reset this flag for re-use later
/*
Assertions and assignments to support them go here.
*/
flags[(mySlot+1) % NTHREADS] = true; // next thread can progress
od;
}
// Init is run first
init {
flags[0] = true;
}
/*
LTL properties here.
*/
Run cs195y_handin mc2
from a directory holding your Promela file (queuelock.pml
). You should receive an email confirming that your handin has worked.