concurrency background and implementation
Download
Skip this Video
Download Presentation
Concurrency: Background and Implementation

Loading in 2 Seconds...

play fullscreen
1 / 70

Concurrency: Background and Implementation - PowerPoint PPT Presentation


  • 150 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Concurrency: Background and Implementation' - trey


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

slide17
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

slide45

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

slide57
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

ad