Synchronization Tools
Synchronization Tools
Background
InP Producer
8 Buffers OutP
Consumer
Bounded-Buffer
#define BUFFER_SIZE = n
n-1 0
typedef struct
1
{
….
} item ;
… 2
item next_produced;
while (true)
{
/* produce an item in next produced */
buffer[in] = next_produced;
in = (in + 1) % BUFFER_SIZE;
counter++;
}
Consumer
item next_consumed ;
while (true) {
while (counter == 0) ;
/* do nothing */
next_consumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
counter--;
/* consume the item in next consumed */
}
Producer/Consumer with Busy Waiting
The statements
counter++;
counter--;
register1 = counter
register1 = register1 + 1
counter = register1
register2 = counter
register2 = register2 – 1
counter = register2
Bounded Buffer
do {
entry section
critical section
exit section
reminder section
} while (1);
Algorithm 1
do {
while (turn != i);
critical section
turn = j;
remainder section
} while (true);
Shared variables:
int turn;
initially turn = 0
Process Pi
do {
while (turn != i) ;
critical section
turn = j;
reminder section
} while (1);
Shared variables
boolean flag[2];
initially flag [0] = flag [1] = false
flag [i] = true Pi ready to enter its critical section
Process Pi
do {
flag[i] = true;
while (flag[j]);
critical section
flag[i] = false;
remainder section
} while (1);
Algorithm 2
do {
flag[i] = true;
turn = j;
while (flag[j] && turn = = j);
critical section
flag[i] = false;
remainder section
} while (true);
Combined shared variables of algorithms 1 and 2
Peterson’s Solution
Shared variables:
int turn;
initially turn = 0 or 1
initially flag [0] = flag [1] = false
Process Pi
do {
flag [i]:= true;
turn = j;
while (flag [j] and turn == j);
critical section
flag [i] = false;
remainder section
} while (1);
j =1 − i.
Peterson’s Solution
critical section
release lock
remainder section
} while (TRUE);
Synchronization Hardware
1. Executed atomically
2. Returns the original value of passed parameter
3. Set the new value of passed parameter to “TRUE”.
Solution using test_and_set()
do {
while (test_and_set(&lock)) ;
/* critical section */
lock = false;
/* remainder section */
} while (true);
compare_and_swap Instruction
if (*value == expected)
*value = new_value;
return temp;
}
1. Executed atomically
2. Returns the original value of passed parameter “value”
3. Set the variable “value” to “new_value”
only if “value” ==“expected ( under condition).
Solution using compare_and_swap
do
{
while(compare_and_swap(&lock,0,1)!=0);
/* critical section */
lock = 0;
/* remainder section */
} while (true);
Bounded-waiting Mutual Exclusion
with test_and_set
do {
waiting[i] = true;
key = true;
while (waiting[i] && key)
key = test_and_set(&lock);
waiting[i] = false;
/* critical section */
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
else
waiting[j] = false;
/* remainder section */
} while (true);
Mutex Locks
acquire() {
while (!available) ; /* busy wait */
available = false;;
}
release() {
available = true;
}
do {
acquire lock
critical section
release lock
remainder section
} while (true);
Semaphore
wait(S) {
while (S <= 0); // busy wait
S--;
}
signal(S) {
S++;
}
Semaphore Usage
Two operations:
block – place the process invoking the operation
on the appropriate waiting queue
wakeup – remove one of processes in the
waiting queue and place it in the ready queue
Semaphore Implementation with no
Busy waiting
typedef struct{
int value;
struct process *list;
} semaphore;
Semaphore Implementation with no
Busy waiting
wait(semaphore *S) {
S->value--;
if (S->value < 0) {
add this process to S->list;
block();
}
}
signal(semaphore *S) {
S->value++;
if (S->value <= 0) {
remove a process P from S->list;
wakeup(P);
}
}
Deadlock and Starvation
Deadlock and Starvation
P0 P1
wait(S); wait(Q);
wait(Q); wait(S);
... ...
signal(S); signal(Q);
signal(Q); signal(S);
Deadlock and Starvation