Outline for 1/12/98

Point where we will begin on 1/14/98

  • Last time: Processes vs. threads, race conditions, and critical sections defined.

  • Administrative details: none today.
  • Objective: Alternatives for implementing Mutual Exclusion, Synchronization primitives.


    Hardware Assistance

  • Most modern architectures provide some support for building synchronization: atomic read-modify-write instructions.

  • Example: test-and-set (loc, reg)
    [ sets bit to 1 in the new value of loc;
    returns old value of loc in reg ]

  • Other examples: compare-and-swap, fetch-and-op


    Busywaiting with Test-and-Set

    Declare a shared memory location to represent a busyflag on the critical section we are trying to protect.

  • enter_region (or acquiring the "lock"):

    waitloop: tsl busyflag, R0 // R0 = busyflag; busyflag = 1
    bnz R0, waitloop // was it already set?

  • exit region (or releasing the "lock"):

    busyflag = 0

  • Fairness? no.

    Pros and Cons of Busywaiting

  • Key characteristic - the "waiting" process is actively executing instructions in the CPU and using memory cycles.

  • Appropriate when: High likelihood of finding the critical section unoccupied or estimated wait time is very short

  • Disadvantages: Wastes resources (CPU, memory, bus bandwidth)


    Blocking Synchronization

  • OS implementation involving changing the state of the "waiting" process from running to blocked.

  • Need some synchronization abstraction known to OS - provided by system calls.


    Template for Implementing Blocking Synchronization

    Associated with the lock is a memory location (busy) and a queue for waiting threads/processes.

  • Acquire syscall:

    while (busy) {enqueue caller on lock's queue}

    /*upon waking to nonbusy lock*/ busy = true;

  • Release syscall:

    busy = false;

    /* wakup */ move any waiting threads to Ready queue


    Pros and Cons of Blocking

  • Waiting processes/threads don't consume resources

  • Appropriate: when the cost of a system call is justified by expected waiting time

  • Disadvantage: OS involvement -> overhead


    Semaphores

    Well-known synchronization abstraction

    Defined as a non-negative integer with two atomic operations

    P(s) - [wait until s > 0; s--]

    V(s) - [s++]

    The atomicity and the waiting can be implemented by either busywaiting or blocking solutions.


    Semaphore Usage

  • Binary semaphores can provide mutual exclusion (solution of critical section problem)

  • Counting semaphores can represent a resource with multiple instances (e.g. solving producer/consumer problem)

  • Signalling events (persistant events that stay relevant even if nobody listening right now)


    Classic Problems

    There are a number of "classic" problems that represent a class of synchronization situations

  • Critical Section problem

  • Producer/Consumer problem

  • Reader/Writer problem

  • 5 Dining Philosophers


    Producer / Consumer

    Producer:

    while(whatever)

    { locally generate item

    /* fill in synchronization*/

    fill empty buffer with item

    /* fill in synchronization*/

    }

    Consumer:

    while(whatever)

    {

    /* fill in synchronization*/

    get item from full buffer;

    /* fill in synchronization*/

    Use item; }


    5 Dining Philosophers

    Template for Philosopher

    while (food available)

    { /*pick up forks*/

    eat;

    /*put down forks*/

    think awhile;

    }


    Philosophy 101
    (or why 5DP is interesting)

  • How to eat with your Fellows without causing Deadlock.

  • Why Starvation exists and what we can do about it.