Concurrency background and implementation
This presentation is the property of its rightful owner.
Sponsored Links
1 / 70

Concurrency: Background and Implementation PowerPoint PPT Presentation


  • 100 Views
  • Uploaded on
  • Presentation posted in: General

Concurrency: Background and Implementation. Fred Kuhns ([email protected], http://www.arl.wustl.edu/~fredk) Department of Computer Science and Engineering Washington University in St. Louis. Concurrency: Origins and problems. Context Processes need to communicate

Download Presentation

Concurrency: Background and Implementation

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Concurrency background and implementation

Concurrency: Background and Implementation

Fred Kuhns

([email protected], http://www.arl.wustl.edu/~fredk)

Department of Computer Science and Engineering

Washington University in St. Louis


Concurrency origins and problems

Concurrency: Origins and problems

  • Context

    • Processes need to communicate

    • Kernel communication/controlling hardware resources (for example I/O processing)

  • Issues:

    • How is information exchanged between processes (shared memory or messages)?

    • How to prevent interference between cooperating processes (mutual exclusion)?

    • How to control the sequence of process execution (conditional synchronization)?

    • How to manage concurrency within the OS kernel?

  • Problems:

    • Execution of the kernel may lead to concurrent access to state

    • Deferred processing pending some event

    • Processes explicitly sharing resource (memory)

  • Problems with shared memory

    • Concurrent programs may exhibit a dependency on process/thread execution sequence or processor speed (neither are desirable!)

      • race condition – who’s first, and who goes next. affects program results.

  • There are two basic issues resulting from the need to support concurrency:

    • Mutual exclusion: ensure that processes/threads do not interfere with one another, i.e. there are no race conditions. In other words, program constraints (assumptions) are not violated.

    • Conditional synchronization: Processes/threads must be able to “wait” for the data to arrive or constraints (assertions) to be satisfied.

CSE522– Advanced Operating Systems


Definitions

Definitions

  • Process: sequence of statements which are implemented as one or more primitive atomic operations (hardware instructions)

  • Concurrent program: results in the interleaving of statements from different processes

  • Program state: value of a program’s variables at a given point in time.

    • Execution viewed as a sequence of states si.

    • Atomic actions transform states.

  • Program history: specific sequence of program states: s0 -> s1 -> ... -> sN

    • Synchronization constrains the set of possible histories to only those that are desirable

  • Mutual Exclusioncombines a sequence of actions into a critical sectionwhich appear to execute atomically.

CSE522– Advanced Operating Systems


Interference or race conditions

Interference or Race Conditions

  • If two or more process access and modify shared data concurrently, and the final value of the shared data depends on the order in which it was accessed.

  • Race condition manifest themselves as intermittent problems and are generally difficult to debug.

  • To prevent race conditions, concurrent processes must synchronize their access to the shared memory locations: known as the critical section problem.

CSE522– Advanced Operating Systems


Race conditions example

Race Conditions - Example

  • There are 4 cases for x:

    • case 1: task A runs to completion first loading y=0 then z=0. x = 0 + 0 = 0

    • case 2: Task B runs loading y=1, then Task A runs loading y=1 and z=0. x = 1 + 0 = 1

    • case 3: Task A runs loading y=0, then Task B runs to completion, then Task A runs loading z=2.x = 0 + 2 = 2

    • case 4: Task B runs to completion, then Task A runs loading y=1, z=2,x = 1 + 2 = 3

  • Example 1

    • int y = 0, z = 0;

    • Task A {

    • x = y + z;

    • }

    • Task B {

    • y = 1; z = 2;

    • }

  • Results:

    • x = {0, 1, 2, 3}

    • load y into R0

    • load z into R1

    • set R0 = R0 + R1

    • set x = R0

CSE522– Advanced Operating Systems


Race condition os example

Kernel File Table

0

myfile.c: attributes

myfile.o: attributes

1

...

NULL

7

...

Race Condition: OS Example

Task A:

...

get KFT_NextFree = (7)

-- preempted –-

KFT_NextFree += 1;

update entry 7

Task B:

...

get KFT_NextFree = (7)

KFT_NextFree += 1;

update Entry 7

-- preempt

KFT_NextFree = 7

  • Final value of kernel table entry 7 is indeterminate.

  • Final value of KFT_NextFree is 9

  • Kernel File Table entry 8 is not allocated

CSE522– Advanced Operating Systems


Properties

Properties

  • Property := something that is always true of a program

  • Safety : never enter a bad state

    • Examples: absence of deadlock, providing mutual exclusion

  • Liveness : eventually enter a good state, in particular that a process or thread makes progress toward a “goal” state.

    • Examples: process eventually enters a critical section, a service request is eventually honored, a message eventually reaches its destination

    • May depend on the fairness of scheduler

  • Partial Correctness: if the program terminates then the final answer is correct.

    • Safety property.

    • It says nothing about whether the program will terminate only that if it does then the answer will be correct.

  • Total Correctness: combines partial correctness with termination.

    • Liveness property

    • Says that a program will indeed always terminate (i.e. complete) and produce a valid (correct) answer.

  • Mutual exclusion is a safety property (no bad states).

CSE522– Advanced Operating Systems


Fairness

Fairness

  • Unconditional fairness:a scheduling policy is unconditionally fair if every unconditional atomic action that is eligible is executed eventually.

    • round-Robin is unconditionally fair in the absence of conditional atomic expressions (atomic expression awaits some condition to be true before being executed).

    • If conditional expressions are present then need stronger guarantees.

  • Weak fairness: A scheduling policy is weakly fair if 1) it is unconditionally fair and 2) every conditional atomic action that is eligible is executed eventually, assuming that its condition becomes true and then remains true until it is seen by the process executing the conditional atomic action.

    • ensures that every process keeps getting chances

    • progress then depends on the possibility that the process will get a chance at the right time

  • Strong fairness: A scheduler is strongly fair if 1) it is unconditionally fair and 2) every conditional atomic action that is eligible is executed eventually, assuming that its condition is infinitely often true.

CSE522– Advanced Operating Systems


Some definitions

Some Definitions

  • Independent processes: Two processes are independent if the write set of each is disjoint from both the read and write sets of the other.

  • Critical reference: reference to a variable changed by another process. Assume the variable is written or read atomically.

  • Critical assertion: A pre/post condition that is not in a critical section.

  • Noninterference: An assignment a and its precondition pre(a) in process A does not interfere with a critical assertion C in another process if the following is always true. {C ^ pre(a)} a {C}That is, C is not affected by the execution of a when pre(a) is true.

CSE522– Advanced Operating Systems


Avoiding race conditions

Avoiding Race Conditions

  • At-Most-Once property: If the assignment statement x = e satisfies1)e contains at most one critical reference and x is not read by another process or 2)e contains no critical references, in which case x may be read by another process.In other words, there can be at most one critical reference within the expression S: x = e

  • Four techniques for avoiding interference:

    • Disjoint variables : write set of one process is disjoint from the reference set of another. Reference set is the set of variables appearing in assertions.

    • Weakened assertions : if variables are not disjoint then loosen constraints (i.e. the set of assertions).

    • Global invariants : expresses relationships between shared variables

    • Synchronization : define atomic actions

CSE522– Advanced Operating Systems


Consumer producer example

Consumer Producer Example

Producer

item nextProduced;

while (TRUE) {

while (counter == BUFSZ);

buffer[in] = nextProduced;

in = (in + 1) % BUFSZ;

counter++;

}

#define BUFSZ 10

typedef struct { . . . } item;

item buffer[BUFSZ];

int in = 0;

int out = 0;

int counter = 0;

Consumer

item nextConsumed;

while (TRUE) {

while (counter == 0) ;

nextConsumed = buffer[out];

out = (out + 1) % BUFSZ;

counter--;

}

critical section.

Must protect the “counter write” critical section.

CSE522– Advanced Operating Systems


Bounded buffer

Bounded Buffer

  • If both the producer and consumer attempt to update the buffer concurrently, the assembly language statements may get interleaved.

  • Interleaving depends upon how the producer and consumer processes are scheduled.

  • Assume counter is initially 5. One interleaving of statements is:producer: register1= counter(register1= 5)producer: register1= register1 + 1(register1= 6)consumer: register2= counter(register2= 5)consumer: register2= register2 – 1(register2= 4)producer: counter= register1(counter= 6)consumer: counter= register2 (counter= 4)

  • The value of count may be either 4 or 6, where the correct result should be 5.

CSE522– Advanced Operating Systems


Critical section problem

Critical Section Problem

Entry/exit protocol satisfies:

  • Mutual Exclusion: At most one process may be active within the critical section

  • Absence of deadlock (livelock): if two or more processes attempt to enter CS, one will eventually succeed.

  • Absence of Unnecessary delay: If one process attempts to enter CS and all other processes are either in their non-critical sections or have terminated then it is not prevented from entering.

  • Eventual entry (no starvation, more a function of scheduling): if a process is attempting to enter CS it will eventually be granted access.

Task A {

while (True) {

entry protocol;

critical section;

exit protocol;

non-critical section;

}

}

CSE522– Advanced Operating Systems


Mutual exclusion

Mutual Exclusion

  • First we look at mutual exclusion alone, also known as busy waiting

    • Simplest approach (on single processor systems) is to disable interrupts

      • why does this work?

      • traditional kernels use this approach

      • less attractive for user process. why?

    • Algorithms implemented in software without support from the hardware

    • Hardware support for atomic read/write operations

  • Then we look at a solution which puts a process to sleep when a resource is not available, permitting more efficient use of the system (conditional synchronization: sleep until the condition is true)

CSE522– Advanced Operating Systems


Mutual exclusion interrupt disabling

Mutual Exclusion - Interrupt Disabling

  • Process runs until requests OS service or interrupted

  • Process disables interrupts for mutual exclusion

  • Processor has limited ability to interleave programs

  • Efficiency of execution may be degraded

  • Multiprocessing

    • disabling interrupts on one processor will not guarantee mutual exclusion. Why?

  • Entry/exit protocol satisfies (*single CPU):

    • Mutual Exclusion:Yes

    • Absence of deadlock:Yes

    • Absence of Unnecessary delay:Yes

    • *Eventual entry:Yes

CSE522– Advanced Operating Systems


Lock variables

Lock Variables

Process A {

while (True){

//entry protocol

while (lock == 1);

lock = 1;

critical section;

// exit protocol

lock = 0;

non-critical;

}

}

int lock = 0;

Process B {

while (True) {

// entry protocol

while (lock == 1);

lock = 1;

critical section;

// exit protocol

lock = 0;

non-critical;

}

}

CSE522– Advanced Operating Systems


Concurrency background and implementation

Lock

Entry/exit protocol satisfies:

  • Mutual Exclusion: No

  • Absence of deadlock: Yes

  • Absence of Unnecessary delay: Yes

  • Eventual entry: No

CSE522– Advanced Operating Systems


Taking turns

Taking Turns

Task A {

int myid = 0;

while (True) {

// entry protocol

while (turn != 0) ;

critical section;

// exit protocol

turn = 1;

non-critical;

}

}

int turn = 0;

Task B {

int myid = 1;

while (True) {

// entry protocol

while (turn != 1) ;

critical section;

// exit protocol

turn = 0;

non-critical;

}

}

CSE522– Advanced Operating Systems


Taking turns1

Taking turns

Entry/exit protocol satisfies:

  • Mutual Exclusion: Yes

  • Absence of deadlock: Yes

  • Absence of Unnecessary delay: No

  • Eventual entry: Yes

CSE522– Advanced Operating Systems


Combined approach

Combined Approach

aka Peterson’s Solution

Process A {

int myid = 0;

while (1) {

enter(myid);

critical section;

leave(myid);

}

}

#define N 2

int last = 0;

int want[N] = {0,0};

void enter(int proc) {

int other = proc ? 1 : 0;

want[proc] = 1;

last = proc;

while (last == proc && want[other]);

}

void leave(int proc) {

want[proc] = 0;

}

Process B {

int myid = 1;

while (1) {

enter(myid);

critical section;

leave(myid);

}

}

CSE522– Advanced Operating Systems


Peterson s solution

Peterson’s Solution

Entry/exit protocol satisfies:

  • Mutual Exclusion: Yes

  • Absence of deadlock: Yes

  • Absence of Unnecessary delay: Yes

  • Eventual entry: Yes

CSE522– Advanced Operating Systems


Help from hardware

Help from Hardware

  • Special Machine Instructions

    • Performed in a single instruction cycle

    • Not subject to interference from other instructions

    • Reading and writing

    • Reading and testing

  • For example the test and set instruction:

    boolean TSL (boolean &lock) {

    boolean tmp = lock;

    lock = True;

    return tmp;

    }

    You have the lock iff False is returned.

    • if lock == False before calling TSL(lock)

      • it is set to True and False is returned

    • if lock == True before calling TSL(lock)

      • it is set to True and True is returned

CSE522– Advanced Operating Systems


Mutual exclusion with tsl

Mutual Exclusion with TSL

  • Shared data:boolean lock = False; // initialize to false

  • Task Pi

    do {

    // Entry protocol

    while (TSL(lock) == True) ; // spin: wait for lock

    // execute critical section code

    -- critical section --

    // Exit protocol

    lock = False;

    // Non-critical section code

    -- remainder section --

    } while (1);

CSE522– Advanced Operating Systems


Using a swap instruction

Using a Swap Instruction

  • Atomic swap:

    void Swap(boolean &a, boolean &b)

    {int temp = a; a = b; b = temp;};

    Atomically swap values, after calling swap, a == original value of b, b = original value of a

  • Implementing a mutex. Shared data (initialized to False):

    boolean lock = False;

    boolean waiting[n];

    Process Pi

    do {

    // Entry protocol

    key = True;

    // when lock is false key becomes false

    while (key == True) Swap(lock, key) ;

    // Execute critical section code

    -- critical section --

    // Exit protocol

    lock = false;

    // Non-critical section code

    -- remainder section --

    }

CSE522– Advanced Operating Systems


Machine instructions

Machine Instructions

  • Advantages

    • Can be used on single or multi-processor systems (shared memory)

    • It is simple and therefore easy to verify

    • It can be used to support multiple critical sections

  • Disadvantages

    • Busy-waiting consumes processor time

    • Starvation possible when a process leaves a critical section and more than one process is waiting.

      • Who is next? Lowest priority process may never acquire lock.

    • Deadlock - If a low priority process has the critical region (i.e. lock) but is preempted by a higher priority process spinning on lock then neither can advance.

CSE522– Advanced Operating Systems


Must we always busy wait

Must we always busy wait?

  • While busy waiting is useful in some situations it may also lead to other problems: inefficient use of CPU and deadlock resulting from a priority inversion

  • What we really want is a way to combine mutual exclusion schemes with conditional synchronization.

  • In other words, we want the option of blocking a process until it is able to acquire the mutual exclusion lock.

  • Simple solution is to add two new functions:

    • sleep() and wakeup()

CSE522– Advanced Operating Systems


Adding conditional synchronization almost a complete solution

Adding Conditional Synchronization: Almost a Complete Solution

int N 10

int buf[N];

int in = 0, out = 0, cnt = 0;

Task producer {

int item;

while (1) {

item = mkitem();

if (cnt == N)

sleep();

buf[in] = item;

in = (in + 1) % N;

lock(lock);cnt++;unlock(0);

if (cnt == 1)

wakeup(consumer);

}

}

Task consumer {

item_t item;

while (TRUE) {

if (cnt == 0)

sleep();

item = buf[out];

out = (out + 1) % N;

lock(lock);cnt--;unlock(lock);

if (cnt == N-1)

wakeup(producer);

consume(item);

}

}

CSE522– Advanced Operating Systems


Lost wakeup problem

Lost wakeup problem

  • Assume that the lock() and unlock() functions implement a simple spin lock

    • I’ve left out the details to simplify the previous example

  • There is a race condition that results in a lost wakeup, do you see it?

  • We will solve this problem when we talk about semaphores and monitors.

CSE522– Advanced Operating Systems


Intro to semaphores

Intro to Semaphores

  • Synchronization mechanism:

    • No busy waiting

    • No lost wakeup problem.

  • Integer variable accessible via two indivisible (atomic) operations :

    • P(s) or wait(s):If s > 0 then decrementelse block thread on semaphore queue

    • V(s) or signal(s):If (s == 0 and waiting threads) then wake one sleeping threadelse increment s

    • Kernel guarantees operations are atomic

    • Can define a non-blocking version: trylock.

    • Each Semaphore has an associated wait queue.

  • Ways to use a semaphore:

    • (1) Mutual Exclusion: binary semaphore initialized to 1

    • (2) Event Waiting: binary semaphore initialized to 0

    • (3) Resource counting: Initialized to number of available resources

  • If using for mutual exclusion, semantics ensure lock ownership transfers to waking thread

    • Threads are woken up in FIFO order

    • May result in unnecessary context switches, Semaphore convoys. A thread currently running on another CPU may attempt to lock resource immediately after it has been “transferred” to a sleeping thread. May be better to allow the already running thread to acquire lock and waking thread to wait on ready queue. This reduces the number of context switches.

CSE522– Advanced Operating Systems


Critical section of n tasks

Critical Section of n Tasks

  • Shared data:

    semaphore mutex; // initialize mutex = 1

  • Process Ti: do {wait(mutex); -- critical section --

    signal(mutex); -- remainder section –

    } while (1);

CSE522– Advanced Operating Systems


Semaphore implementation

Semaphore Implementation

  • Define a semaphore as a record

    typedef struct {

    int value; // value of semaphore

    queue_t sq; // task/thread queue

    // also need lock(s) to protect value and thread queue

    } semaphore;

  • Assume two simple operations: wait() and signal()

  • Is the below a complete solution? How do we protect the semaphore object from concurrent access by other threads?

void signal(sem_t *S) {

thread_t t;

S->value++;

if (S->value  0) {

t = getthread(S->sq);wakeup(t);

}

return;

}

void wait(sem_t *S) {

S->value--;

if (S->value< 0) {

addthread(S->sq);

sleep();

}

return;

}

CSE522– Advanced Operating Systems


Some reference background

Some Reference Background

  • Semaphores used in Initial MP implementations

  • Threads are woken up in FIFO order (convoys)

    • forcing a strictly fifo order may result in unnecessary blocking

  • Used to provide

    • Mutual exclusion (initialized to 1)

    • Event-waiting (initialized to 0)

    • Resource counting (initialized to number available)

  • High level abstraction built using lower-level primitives.

    • Always caries the overhead of sleep queue management (event notification mechanism)

    • Always caries the overhead of locking (mutual exclusion mechanism)

  • Hides whether thread has blocked, may want to actively “wait” for resource (i.e. spin lock)

CSE522– Advanced Operating Systems


Potential problems

Potential Problems

  • Incorrect use of semaphores can lead to problems

    • Critical sections using semaphores: must keep to a strict protocol

    • wait(S); {critical section}; signal(S)

  • Problems:

    • No mutual exclusion:

      • Reverse: signal(S); {critical section}; wait(S);

      • Omit wait(S)

    • Deadlock:

      • wait(S); {critical section}; wait(S);

      • Omit signal(S)

CSE522– Advanced Operating Systems


Other synchronization mechanisms

Other Synchronization Mechanisms

  • Mutex - Mutual Exclusion Lock, applies to any primitive that enforces mutual exclusion semantics

  • Condition variables – event notification, usually has an associated predicate and lock to protect predicate.

  • Read/Write Locks – there are other paradigms, for example only requiring exclusive access to a resource if it is being modified. Otherwise any number of readers.

  • Reference Counting – the kernel often has to maintain resources while they are actively used. A thread may indicate its interest in a resource by incrementing a reference count then decrementing when it is done. When the reference count goes to 0 then resource may be freed (garbage collection).

CSE522– Advanced Operating Systems


Multiprocessor support

Multiprocessor Support

  • The traditional approaches do not work.

    • Lost wakeup problem: Between checking a locked flag and placing a thread on a sleep queue (and setting wanted flag) the event may occur.

    • thundering heard problem: waking all threads sleeping on a resources may cause them to all to run in parallel (on different CPUs), but only one can lock resource so remainder go back to sleep.

  • Kernel relies on interrupt disabling to protect one processors context but this is not enough for multiple processors:

    • need both interrupt disabling and spin locks

  • Leverage Hardware support for synchronization

    • Atomic test-and-set: test bit, set it to 1, return old value.

    • load-linked and store-conditional (read-modify-write): load variable, modify then store. A flag is set indicating if the write was successful – can be used to implement semaphores (atomic increment, keep trying until you succeed in incrementing variable).

CSE522– Advanced Operating Systems


Spin locks mp support

Spin Locks (MP Support)

  • The idea is to provide a basic, HW supported primitive with low overhead.

  • Lock held for short periods of time

  • If locked, then busy-wait on the resource

  • Must not give up processor if holding lock!

  • I show interrupts being blocked

  • For a mutual exclusion lock you must also block interrupts!

void lock (spinlock_t *s)

{

while (testNset(s) != 0)

while (*s != 0) ;

}

void unlock (spinlock_t *s)

{

s = 0;

}

CSE522– Advanced Operating Systems


Blocking locks mutex

Blocking Locks/Mutex

  • Allows threads to block

  • Interface: lock(), unlock () and trylock ()

  • Consider traditional kernel locked flag

  • Mutex allows for exclusive access to flag, solving the race condition

  • flag can be protected by a spin lock.

CSE522– Advanced Operating Systems


Condition variables

Condition Variables

  • Associated with a predicate which is protected by a mutex (usually a spin lock).

  • Useful for event notification

  • Can wakeup (signal) one or all (broadcast) sleeping threads.

  • Up to 3 or more mutex locks are typically required:

    • one for the predicate

    • one for the sleep queue (or CV list)

    • one or more for the scheduler queue (swtch ())

  • Deadlock avoided by requiring a strict order

CSE522– Advanced Operating Systems


Condition variables1

predicate

Condition variable

mutex

List of blocked threads

mutex (for list)

kthread_3

kthread_2

kthread_1

Condition Variables

update predicate

wake up one thread

Thread sets event

CSE522– Advanced Operating Systems


Cv implementation

CV Implementation

void signal (cv *c)

{

lock (&cv->listlock);

remove a thread from list

unlock (&cv->listlock);

if thread, make runnable;

return;

}

void broadcast (cv *c)

{

lock (&cv->listlock);

while (list is nonempty) {

remove a thread

make it runnable

}

unlock (&cv->listlock);

return;

}

void wait (cv *c, mutex_t *s)

{

lock (&cv->listlock);

add thread to queue

unlock (&cv->listlock);

unlock (s);

swtch ();

/* return after wakup */

lock (s);

return;

}

CSE522– Advanced Operating Systems


Monitors

Monitors

  • High-level synchronization construct that allows the safe sharing of an abstract data type among concurrent processes.

    monitor monitor-name {

    shared variable declarations

    procedure body P1 (…) { . . . }

    procedure body P2 (…) { . . . }

    procedure body Pn (…) { . . . }

    { initialization code }

    }

CSE522– Advanced Operating Systems


Monitors condition variables

Monitors: Condition Variables

  • To allow a process to wait within the monitor, a condition variable must be declared, as conditionx, y;

  • Condition variable can only be used with the operations wait and signal

    • x.wait() : the process invoking this operation is suspended until another process invokes x.signal();

    • x.signal : resumes exactly one suspended process. If no process is suspended, then the signal operation has no effect.

  • If a task A within a monitor signals a suspended task B, there is an issue of which process is permitted to execute with the monitor

    • signal-and-wait: Task A must wait while process B is permitted to continue executing within the monitor

    • signal-and-continue: Task A continues to execute within the monitor, task B must wait

  • A case can be made for either approach

CSE522– Advanced Operating Systems


Monitor with condition variables

Monitor With Condition Variables

CSE522– Advanced Operating Systems


Monitor implementation

Monitor Implementation

  • Since only one task may be active in a monitor there must be a mutex protecting the monitor.

    • The mutex effectively serializes access to the monitor.

  • We also need to account for sending signals within a monitor – that is, guard against having more than one active task within the monitor.

  • Our implementation uses semaphores for both mutual exclusion (initialized to 1 for a mutex) and counting the number of tasks waiting to be resumed within the monitor (initialized to 0 – counting semaphore)

CSE522– Advanced Operating Systems


Concurrency background and implementation

Example using Hoare Semantics; signal-and-wait

for CV x define:

semaphore xSem = 0;

int xCnt = 0;

x.wait(…) {

xCnt++;

if (urgCnt > 0) signal(urgent);

else signal(mutex);

wait(xSem);

xCnt--;

}

x.signal(…) {

if (xCnt > 0) {

urgCnt++;

signal(xSem);

wait(urgent);

urgCnt--;

}

}

semaphore mutex = 1;

semaphore urgent = 0;

int urgCnt = 0;

methodX(…) {

// entry protocol

wait(mutex);

… body of M; …

// exit protocol

if (urgCnt > 0)

signal(urgent)

else

signal(mutex);

}

CSE522– Advanced Operating Systems


Cv hoare signal and wait

CV: Hoare; signal-and-wait

semaphore mutex = 1;

semaphore urgSem = 0, cvSem = 0;

int urgCnt = 0, cvCnt = 0;

wait() {

cvCnt++;

if (urgCnt > 0)

signal(urgSem);

else

signal(mutex);

wait(cvSem);

cvCnt--;

}

signal() {

urgCnt++;

if (cvCnt > 0) {

signal(cvSem);

wait(urgSem);

}

urgCnt--;

}

CSE522– Advanced Operating Systems


Cv mesa signal and continue

CV: Mesa; signal-and-continue

  • Implement so that the signaling task continues

semaphore monLock = 1; // monitor mutex

semaphore cvSem = 0;

cv.wait() {

wait(cvSem);

wait(monLock);

}

cv.signal() {

signal(cvSem);

}

CSE522– Advanced Operating Systems


More on monitor implementations

More on Monitor Implementations

  • How can we control the task resumption order?

  • Conditional-wait construct: x.wait(c);

    c – integer expression evaluated when wait executed.

    • value of c (a priority number) stored with the name of the process that is suspended.

    • when x.signal is executed, process with smallest associated priority number is resumed next.

  • Verifying correctness: Check two conditions:

    • User processes must always make their calls on the monitor in a correct sequence.

    • Must ensure that an uncooperative process does not ignore the mutual-exclusion gateway provided by the monitor, and try to access the shared resource directly, without using the access protocols.

  • CSE522– Advanced Operating Systems


    Critical regions

    Critical Regions

    • High-level synchronization construct

    • A shared variable v of type T, is declared as:

      v: shared T

    • Variable v accessed only inside statement

      region v when B do Swhere B is a Boolean expression.

    • While statement S is being executed, no other process can access variable v.

    CSE522– Advanced Operating Systems


    Critical regions1

    Critical Regions

    • Regions referring to the same shared variable exclude each other in time.

    • When a process tries to execute the region statement, the Boolean expression B is evaluated. If B is true, statement S is executed. If B is false, the process is delayed until B becomes true and no other process is in the region associated with v.

    CSE522– Advanced Operating Systems


    Reader writer locks

    Reader/Writer Locks

    • Many readers, one writer

    • Writer can only acquire lock if no readers are active - lockexclusive (rwlock_t *r)

    • Any reader can acquire lock if no writers are active - lockshared (rwlock_t *r)

    • There is a perhaps subtle issue with releasing the lock, do you schedule a waiting writer or the readers?

      • wake all waiting threads, readers and writers

      • wake a waiting writer

      • wake the waiting readers

    CSE522– Advanced Operating Systems


    Rw locks

    RW Locks

    • Preferred solution limits both the number of context switches and addresses the starvation issue:

      • writer wakes up all sleeping readers, or another writer if no waiting readers.

      • last reader to release lock wakes one waiting writer.

      • to avoid writer starvation, if there is a waiting writer then future readers are blocked until all readers release lock and a writer gets to run.

    • What about when a reader wants to upgrade to an exclusive lock?

      • if two readers both call upgrade while holding the shared lock, then deadlock. So require shared lock to be released, but this means a writer could sneak in and change object, solution would be to give preference to reader's upgrade

      • multiple upgrade requests are problematic, could return fail and release lock, thread then would “know” that it must request an exclusive lock.

    CSE522– Advanced Operating Systems


    Reference counts

    Reference Counts

    • Protects object when there are outstanding references

    • Consider the case where several threads have a reference (i.e. pointer) to a data object. If one thread releases the object (i.e. free) and the kernel reallocates the object then the other threads have invalid references (which they may try to use!).

    • fix: kernel reference counts objects.

      • When kernel provides reference to object it increments the reference count

      • when process releases the object then reference count is decremented.

    • when reference count goes to zero, there are guaranteed to be no outstanding references to the object.

    CSE522– Advanced Operating Systems


    Considerations

    Considerations

    • Deadlock avoidance:

      • hierarchical - impose order on locks

      • stochastic locking - when violating hierarchy, use trylock so you do not block.

    • Recursive Locks - attempting to acquire a lock already owned by a thread succeeds.

    • Adaptive Locks (Mutex)

      • depending on circumstances and performance considerations, either a spin or blocking lock is used.

    • Protecting invariants, predicates, data, operations (monitors).

    • Granularity and Duration.

    CSE522– Advanced Operating Systems


    Svr4 2 mp

    SVR4.2/MP

    • Basic Locks: nonrecursive mutex, short-term, thread may not block

    • Read-Write Locks: nonrecursive; short-term; thread may not block; single-writer, multiple reader semantics.

    • Sleep Locks: nonrecursive locks, long-term, thread may block.

    • Synchronization variable (condition variable).

    CSE522– Advanced Operating Systems


    Solaris

    Solaris

    • Types:

      • Mutexes - spin, adaptive.

      • Condition Variables

      • Counting Semaphores

      • Multiple-Reader, Single-Writer

    • Queuing mechanism:

      • turnstiles - used for mutexes, reader/writer and semaphores

      • sleep queues - condition variables.

    CSE522– Advanced Operating Systems


    Concurrency background and implementation

    NT

    • Spin lock, kernel & executive only.

    • Executive resources. Provide exclusive and shared read. Kernel mode only.

    • Dispatcher object (kernel supplies to executive). Exposed to win32 apps. Essentially an event queue. Only two states: Signaled or NonSignaled.

    CSE522– Advanced Operating Systems


    Traditional unix kernel

    Traditional UNIX kernel

    • Kernel is

      • reentrant

      • nonpreemptive

    • Interrupt masking

      • interrupt priority level (ipl)

      • kernel can set the current ipl to block interrupts

    • Synchronization uses two flags: locked and wanted

      • process wanting resource

        • if locked then sleep, otherwise set locked flag

      • process holding resource

        • when done,

        • if wanted flag, then call wakeup on wait channel

    • How is access to these two flags synchronized?

    CSE522– Advanced Operating Systems


    Wait channel

    Wait Channel

    • sleep (wait_channel, priority)

    • special wait channels

      • lbolt - awakened by scheduler once per second

      • wait syscall - parent waits on its proc structure

      • sigpause syscall - wait on user structure (u.area)

    • wakeup (wait_channel) - all processes sleeping on a wait channel are made ready.

    CSE522– Advanced Operating Systems


    Wait channels and sleep qs

    Resource X

    locked: 1

    wanted: 1

    P7

    Wait Channels and Sleep Qs

    Owns resource

    0xf1023450

    Sleep Queues

    Hash

    function

    Index

    P4

    P5

    P6

    X

    X

    X

    Queue of processes “waiting” for some resources

    which hashes to this index value.

    CSE522– Advanced Operating Systems


    Wait channel limitations

    Wait Channel Limitations

    • Multiple events map to the same wait channel

    • Multiple resources map to the same wait channel

    • Does not support more complex protocols such as readers-writers

    CSE522– Advanced Operating Systems


    Wait channels limitations

    Resource X

    locked: 1

    wanted: 1

    Wait Channels - Limitations

    Sleep Queues

    Hash

    function

    Resource Y

    P4

    P5

    P6

    locked: 1

    Y

    X

    X

    wanted: 1

    CSE522– Advanced Operating Systems


    Classical problems of synchronization

    Classical Problems of Synchronization

    • Bounded-Buffer Problem

    • Readers and Writers Problem

    • Dining-Philosophers Problem

    CSE522– Advanced Operating Systems


    Bounded buffer problem semaphore solution

    Bounded-Buffer Problem: Semaphore Solution

    • Solves the lost wakeup problem

    • Shared data:semaphore full = 0, empty = n, mutex = 1;

    Producer:

    do {

    …produce item …

    wait(empty);

    wait(mutex);

    … add item to buffer …

    signal(mutex);

    signal(full);

    } while (1);

    Consumer:

    do {

    wait(full)

    wait(mutex);

    … remove item …

    signal(mutex);

    signal(empty);

    … consume item in …

    } while (1);

    CSE522– Advanced Operating Systems


    Bounded buffer using monitors

    Bounded Buffer using Monitors

    monitor ProduceConsume {

    cv full, empty;

    int cnt = 0;

    insert(item_t item) {

    if (cnt == N) wait(full);

    … insert item …

    if (cnt++ == 0) signal(empty);

    }

    item_t remove() {

    if (cnt == 0) wait(empty);

    … remove item …

    if (cnt-- == N) signal(full);

    }

    }

    monitor ProduceConsume PC;

    produce () {

    while (1) {

    …produce item …

    PC.insert(item);

    }

    }

    consume () {

    while (1) {

    item = PC.remove();

    … consume item …

    }

    }

    CSE522– Advanced Operating Systems


    Critical regions bounded buffer

    Critical Regions: Bounded Buffer

    struct buffer {

    int pool[n];

    int count, in, out;

    }

    Producer:

    region buffer

    when (count < n)

    {

    pool[in] = nextp;

    in = (in+1) % n;

    count++;

    }

    Consumer:

    region buffer

    when (count > 0)

    {

    nextc = pool[out];

    out = (out+1) % n;

    count--;

    }

    CSE522– Advanced Operating Systems


    Readers writers

    Readers-Writers

    • Reader tasks and writer tasks share a resource, say a database

    • Many readers may access a database without fear of data corruption (interference)

    • However, only one write may access the database at a time (all other readers and writers must be “locked” out of database.

    • Solutions:

      • simple solution gives priority to readers. Readers enter CS regardless of whether a write is waiting

        • writers may starve

      • second solution requires once a write is ready, it gets to perform its write as soon as possible

        • readers may starve

    CSE522– Advanced Operating Systems


    Readers writers problem

    Readers-Writers Problem

    semaphore mutex = 1, wrt = 1;

    int rdrcnt = 0;

    Reader

    // enter rdrcnt C.S.

    wait(mutex);

    rdrcnt++;

    if (rdrcnt == 1)

    // get reader lock

    wait(wrt);

    // exit rdrcnt C.S.

    signal(mutex);

    … reading is performed …

    // enter rdrcnt C.S

    wait(mutex);

    rdrcnt--;

    if (rdrcnt == 0)

    // release reader lock

    signal(wrt);

    signal(mutex):

    // exit rdrcnt C.S.

    Writer

    // get exclusive lock

    wait(wrt);

    … modify object …

    // release exclusive lock

    signal(wrt);

    CSE522– Advanced Operating Systems


    Dining philosophers problem

    Dining-Philosophers Problem

    semaphore chopstick[5] = {{1}, {1}, {1}, {1}, {1}};

    Philosopher i:

    do {

    wait(chopstick[i])

    wait(chopstick[(i+1) % 5])

    … eat …

    signal(chopstick[i]);

    signal(chopstick[(i+1) % 5]);

    … think …

    } while (1);

    This solution can suffer from starvation, do you see why?

    CSE522– Advanced Operating Systems


    Dining philosophers example

    Dining Philosophers Example

    monitor dp {

    enum {think,hungry,eat} state[5];

    condition self[5];

    void pickup(int i) ;

    void putdown(int i);

    void test(int i);

    void init() {

    for (int i=0; i<5;++i)

    state[i] = think;

    }

    }

    void putdown(int i) {

    state[i] = think;

    // test left and right

    test((i+4)%5);

    test((i+1)%5);

    }

    void pickup(int i) {

    state[i] = hungry;

    test(i);

    if (state[i] != eat)

    self[i].wait();

    }

    void test(int i) {

    if ((state[(i+4)%5] != eat)

    && (state[i] == hungry)

    && (state[(i+1)%5] != eat))

    {

    state[i] = eat;

    self[i].signal();

    }

    }

    Solution:

    dp.pickup(i);

    ... eat ...

    dp.putdown(i);

    CSE522– Advanced Operating Systems


  • Login