Docstoc

Process-Thread-Sync

Document Sample
Process-Thread-Sync Powered By Docstoc
					Processes, Threads,
Synchronization


  CS 519: Operating System Theory
  Computer Science, Rutgers University


  Instructor: Thu D. Nguyen
  TA: Xiaoyan Li


  Spring 2002
                            Von Neuman Model


Both text (program) and data reside in memory
Execution cycle
     Fetch instruction
     Decode instruction                 CPU
     Execute instruction




                                       Memory




Computer Science, Rutgers          2      CS 519: Operating System Theory
              Image of Executing Program

      100       load R1, R2
      104       add R1, 4, R1         R1: 2000
                                      R2:
      108       load R1, R3           R3:
                                      PC: 100
      112       add R2, R3, R3
                                         CPU
                …
      2000 4
      2004 8
                  Memory

Computer Science, Rutgers        3   CS 519: Operating System Theory
        How Do We Write Programs Now?

public class foo {

     static private int yv = 0;
     static private int nv = 0;
                                   How to map a program
     public static void main() {   like this to a Von
        foo foo_obj = new foo;
        foo_obj->cheat();          Neuman machine?
     }                               Where to keep yv, nv?
     public cheat() {                What about foo_obj and
        int tyv = yv;                tyv?
        yv = yv + 1;
                                     How to do foo->cheat()?
        if (tyv < 10) {
            cheat();
        }
     }
}
Computer Science, Rutgers    4        CS 519: Operating System Theory
                            Global Variables


Dealing with “global” variables like yv and nv is easy
     Let’s just allocate some space in memory for them
     This is done by the compiler at compile time
     A reference to yv is then just an access to yv’s location in
     memory
     Suppose g is stored at location 2000
     Then, yv = yv + 1 might be compiled to something like
          loadi     2000, R1
          load      R1, R2
          add       R2, 1, R2
          store     R1, R2


Computer Science, Rutgers          5         CS 519: Operating System Theory
                            Local Variables

What about foo_obj defined in
main() and tyv defined in                2000                               yv
cheat()?                                 2004                               nv
1st option you might think of is         2008                               foo_obj
just to allocate some space in                                              tyv
memory for these variables as
well (as shown to the right)
     What is the problem with this
     approach?
     How can we deal with this
     problem?




Computer Science, Rutgers            6          CS 519: Operating System Theory
                            Local Variable

                                                yv                         globals
      foo->cheat();
      tyv = yv;
                                                tyv
      …                                                                   stack
                                                tyv’
      foo->cheat();
                                                tyv’’
      tyv = yv;
      …
Allocate a new memory location to tyv every time cheat() is called at run-
time
Convention is to allocate storage in a stack (often called the control stack)
Pop stack when returning from a method: storage is no longer needed
Code for allocating/deallocating space on the stack is generated by
compiler at compile time

Computer Science, Rutgers            7           CS 519: Operating System Theory
               What About “new” Objects?


                            foo foo_obj = new foo;
foo_obj is really a pointer to a foo object
As just explained, a memory location is allocated for
foo_obj from the stack whenever main() is invoked
Where does the object created by the “new foo”
actually live?
     Is the stack an appropriate place to keep this object?
     Why not?




Computer Science, Rutgers            8         CS 519: Operating System Theory
                            Memory Image

Suppose we have executed the         yv                      globals
following:
     yv = 0
     nv = 0                      foo_obj
     main()                         tyv
     foo_obj = new foo                                       stack
                                    tyv’
     foo->cheat()
     tyv = yv                       tyv’’
     yv = yv + 1
     foo->cheat()
     tyv = yv
     yv = yv + 1
     foo->cheat()                                            heap
     tyv = yv
     yv = yv + 1


Computer Science, Rutgers        9          CS 519: Operating System Theory
                            Data Access

How to find data allocated dynamically on stack?
By convention, designate one register as the stack pointer
Stack pointer always point at current activation record
     Stack pointer is set at entry to a method
     Code for setting stack pointer is generated by compiler
Local variables and parameters are referenced as offsets from sp



activation record                                        PC
                     tyv
                                                         SP
for cheat_yes()


                                                          CPU

Computer Science, Rutgers           10           CS 519: Operating System Theory
                              Data Access


The statement
     tyv = tyv + 1
Would then translate into something like
     addi            0, sp, R1   # tyv is the only variable so offset is 0
     load            R1, R2
     addi            1, R2
     store           R1, R2




Computer Science, Rutgers         11           CS 519: Operating System Theory
                            Activation Record

                                        We have only talked about
                                        allocation of local variables on
          Other stuff                   the stack
                                        The activation record is also
       Local variables                  used to store:
                                            Parameters
                                            The beginning of the previous
                                            activation record
                                            The return address
                                            …




Computer Science, Rutgers          12           CS 519: Operating System Theory
           Run Time Storage Organization

                            Each variable must be assigned a storage
             Code           class

           Globals          Global (static) variables
                                Allocated in globals region at compile-
             Stack              time
                            Method local variables and parameters
                                Allocate dynamically on stack
             Heap           Dynamically created objects (using new)
          Memory                Allocate from heap
                                Objects live beyond invocation of a
                                method
                                Garbage collected when no longer “live”

Computer Science, Rutgers         13          CS 519: Operating System Theory
 Why Did We Talk About All That Stuff?


Process = system abstraction for the set of resources
          required for executing a program
             = a running instance of a program
             = memory image + registers’ content (+ I/O
               state)
The stack + registers’ content represent the execution
          context or thread of control




Computer Science, Rutgers      14       CS 519: Operating System Theory
                      What About The OS?

Recall that one of the function of an OS is to provide a virtual
machine interface that makes programming the machine easier
So, a process memory image must also contain the OS

                                                             Code
Memory
                            OS                              Globals
                                                             Stack

                        Code
                       Globals                               Heap
                        Stack         OS data space is used to store things
                                      like file descriptors for files being
                                      accessed by the process, status of I/O
                        Heap          devices, etc.
Computer Science, Rutgers        15           CS 519: Operating System Theory
    What Happens When There Are More
        Than One Running Process?

                OS

                                   Code
                                  Globals
                P0                 Stack


                                   Heap
                P1


                P2



Computer Science, Rutgers   16   CS 519: Operating System Theory
                      Process Control Block

Each process has per-process state maintained by the OS
     Identification: process, parent process, user, group, etc.
     Execution contexts: threads
     Address space: virtual memory
     I/O state: file handles (file system), communication endpoints
     (network), etc.
     Accounting information
For each process, this state is maintained in a process control
block (PCB)
     This is just data in the OS data space
     Think of it as objects of a class



Computer Science, Rutgers            17          CS 519: Operating System Theory
                            Process Creation

How to create a process? System call.
In UNIX, a process can create another process using the fork()
system call
     int pid = fork();       /* this is in C */
The creating process is called the parent and the new process is
called the child
The child process is created as a copy of the parent process
(process image and process control structure) except for the
identification and scheduling state
     Parent and child processes run in two different address spaces
     By default, there’s no memory sharing
     Process creation is expensive because of this copying
The exec() call is provided for the newly created process to run a
different program than that of the parent
Computer Science, Rutgers                 18      CS 519: Operating System Theory
             System Call In Monolithic OS


                                                       interrupt vector for trap instruction
                    PC           PSW                   in-kernel file system(monolithic OS)

               code for fork system call
                                                                  kernel mode
     trap                                       iret

                                                                  user mode


                   id = fork()




Computer Science, Rutgers                  19            CS 519: Operating System Theory
                            Process Creation


                            fork() code

                            PCBs



                            fork()




                            exec()




Computer Science, Rutgers                 20   CS 519: Operating System Theory
  Example of Process Creation Using Fork

The UNIX shell is command-line interpreter whose basic purpose
is for user to run applications on a UNIX system
cmd arg1 arg2 ... argn




Computer Science, Rutgers     21         CS 519: Operating System Theory
                Process Death (or Murder)


One process can wait for another process to finish
using the wait() system call
     Can wait for a child to finish as shown in the example
     Can also wait for an arbitrary process if know its PID
Can kill another process using the kill() system call
     What all happens when kill() is invoked?
     What if the victim process doesn’t want to die?




Computer Science, Rutgers         22        CS 519: Operating System Theory
                            Process Swapping

May want to swap out entire process
     Thrashing if too many processes competing for resources
To swap out a process
     Suspend all of its threads
          Must keep track of whether thread was blocked or ready
     Copy all of its information to backing store (except for PCB)
To swap a process back in
     Copy needed information back into memory, e.g. page table,
     thread control blocks
     Restore each thread to blocked or ready
          Must check whether event(s) has (have) already occurred


Computer Science, Rutgers            23          CS 519: Operating System Theory
                    Process State Diagram



                                   ready
                                     (in
                                  memory)



                            swap out        swap in



                                  suspended
                                (swapped out)




Computer Science, Rutgers              24             CS 519: Operating System Theory
                              Signals


OS may need to “upcall” into user processes
Signals
     UNIX mechanism to upcall when an event of interest occurs
     Potentially interesting events are predefined: e.g.,
     segmentation violation, message arrival, kill, etc.
     When interested in “handling” a particular event (signal), a
     process indicates its interest to the OS and gives the OS a
     procedure that should be invoked in the upcall.




Computer Science, Rutgers         25         CS 519: Operating System Theory
                            Signals (Cont’d)

When an event of interest occurs the
kernel handles the event first, then
modifies the process’s stack to look as
if the process’s code made a procedure
call to the signal handler.
                                                                Handler
When the user process is scheduled
next it executes the handler first              B                   B
From the handler the user process               A                   A
returns to where it was when the event
occurred




Computer Science, Rutgers          26     CS 519: Operating System Theory
              Inter-Process Communication

Most operating systems provide several abstractions
for inter-process communication: message passing,
shared memory, etc
Communication requires synchronization between
processes (i.e. data must be produced before it is
consumed)
Synchronization can be implicit (message passing) or
explicit (shared memory)
Explicit synchronization can be provided by the OS
(semaphores, monitors, etc) or can be achieved
exclusively in user-mode (if processes share memory)


Computer Science, Rutgers   27      CS 519: Operating System Theory
             Inter-Process Communication


More on shared memory and message passing later
Synchronization after we talk about threads




Computer Science, Rutgers   28    CS 519: Operating System Theory
  A Tree of Processes On A Typical UNIX
                 System




Computer Science, Rutgers   29   CS 519: Operating System Theory
                            Process: Summary

System abstraction – the set of resources required for executing
a program (an instantiation of a program)
     Execution context(s)
     Address space
     File handles, communication endpoints, etc.
Historically, all of the above “lumped” into a single abstraction
More recently, split into several abstractions
     Threads, address space, protection domain, etc.
OS process management:
     Supports creation of processes and interprocess communication (IPC)
     Allocates resources to processes according to specific policies
     Interleaves the execution of multiple processes to increase system
     utilization

Computer Science, Rutgers           30             CS 519: Operating System Theory
                            Threads


Thread of execution: stack + registers (which includes
the PC)
     Informally: where an execution stream is currently at in the
     program and the method invocation chain that brought the
     execution stream to the current place
     Example: A called B which called C which called B which called
     C
     The PC should be pointing somewhere inside C at this point
     The stack should contain 5 activation records: A/B/C/B/C
     Thread for short
Process model discussed thus far implies a single thread

Computer Science, Rutgers        31         CS 519: Operating System Theory
                            Multi-Threading

Why limit ourselves to a single thread?
     Think of a web server that must service a large stream of requests
     If only have one thread, can only process one request at a time
     What to do when reading a file from disk?
Multi-threading model
     Each process can have multiple threads
     Each thread has a private stack
          Registers are also private
     All threads of a process share the code and heap
          Objects to be shared across multiple threads should be allocated on the heap




Computer Science, Rutgers                 32            CS 519: Operating System Theory
          Process Address Space Revisited



                    OS                           OS

                   Code                         Code
                 Globals                      Globals
                                               Stack
                  Stack
                                                Stack


                   Heap                         Heap
(a) Single-threaded address space (b) Multi-threaded address space
 Computer Science, Rutgers      33        CS 519: Operating System Theory
                     Multi-Threading (cont)

Implementation
     Each thread is described by a thread-control block (TCB)
     A TCB typically contains
          Thread ID
          Space for saving registers
          Pointer to thread-specific data not on stack
Observation
     Although the model is that each thread has a private stack,
     threads actually share the process address space
      There’s no memory protection!
      Threads could potentially write into each other’s stack


Computer Science, Rutgers              34           CS 519: Operating System Theory
                            Thread Creation


        PC                             thread_create() code
        SP
                                       PCBs

                                       TCBs



                                       thread_create()

                                       new_thread_starts_here

                                       stacks




Computer Science, Rutgers         35            CS 519: Operating System Theory
                            Context Switching

Suppose a process has multiple threads …uh oh … a
uniprocessor machine only has 1 CPU … what to do?
     In fact, even if we only had one thread per process, we would
     have to do something about running multiple processes …
We multiplex the multiple threads on the single CPU
At any instance in time, only one thread is running
At some point in time, the OS may decide to stop the
currently running thread and allow another thread to
run
This switching from one running thread to another is
called context switching

Computer Science, Rutgers          36       CS 519: Operating System Theory
                  Diagram of Thread State




Computer Science, Rutgers   37    CS 519: Operating System Theory
                  Context Switching (cont)


How to do a context switch?
Save state of currently executing thread
     Copy all “live” registers to thread control block
     For register-only machines, need at least 1 scratch register
          points to area of memory in thread control block that registers should
          be saved to

Restore state of thread to run next
     Copy values of live registers from thread control block to
     registers
When does context switching take place?

Computer Science, Rutgers              38          CS 519: Operating System Theory
                  Context Switching (cont)


When does context switching occur?
     When the OS decides that a thread has run long enough and
     that another thread should be given the CPU
          Remember how the OS gets control of the CPU back when it is
          executing user code?
     When a thread performs an I/O operation and needs to block
     to wait for the completion of this operation
     To wait for some other thread
          Thread synchronization: we’ll talk about this lots in a couple of
          lectures




Computer Science, Rutgers               39           CS 519: Operating System Theory
     How Is the Switching Code Invoked?

user thread executing  clock interrupt  PC modified by
hardware to “vector” to interrupt handler  user thread state is
saved for restart  clock interrupt handler is invoked  disable
interrupt checking  check whether current thread has run “long
enough”  if yes, post asynchronous software trap (AST) 
enable interrupt checking  exit interrupt handler  enter
“return-to-user” code  check whether AST was posted  if not,
restore user thread state and return to executing user thread; if
AST was posted, call context switch code


Why need AST?




Computer Science, Rutgers      40         CS 519: Operating System Theory
     How Is the Switching Code Invoked?
                   (cont)

user thread executing  system call to perform I/O 
user thread state is saved for restart  OS code to
perform system call is invoked  I/O operation started
(by invoking I/O driver)  set thread status to waiting
 move thread’s TCB from run queue to wait queue
associated with specific device  call context switching
code




Computer Science, Rutgers   41     CS 519: Operating System Theory
                            Context Switching

                                At entry to CS, the return address is
       BC
                                either in a register or on the stack (in
                                the current activation record)
       CS               BC
                                CS saves this return address to the
                                TCB instead of the current PC
                        UC
                                To thread, it looks like CS just took a
                                while to return!
                        BC          If the context switch was initiated
                                    from an interrupt, the thread never
       BC               CS          knows that it has been context
                                    switched out and back in unless it
                                    looking at the “wall” clock




Computer Science, Rutgers            42         CS 519: Operating System Theory
                  Context Switching (cont)

Even that is not quite the whole story
When a thread is switched out, what happens to it?
How do we find it to switch it back in?
This is what the TCB is for. System typically has
     A run queue that points to the TCBs of threads ready to run
     A blocked queue per device to hold the TCBs of threads blocked
     waiting for an I/O operation on that device to complete
     When a thread is switched out at a timer interrupt, it is still ready to
     run so its TCB stays on the run queue
     When a thread is switched out because it is blocking on an I/O
     operation, its TCB is moved to the blocked queue of the device



Computer Science, Rutgers            43           CS 519: Operating System Theory
     Ready Queue And Various I/O Device
                  Queues




Computer Science, Rutgers   44   CS 519: Operating System Theory
 Switching Between Threads of Different
               Processes

What if switching to a thread of a different process?
Caches, TLB, page table, etc.?
     Caches
          Physical addresses: no problem
          Virtual addresses: cache must either have process tag or must flush
          cache on context switch
     TLB
          Each entry must have process tag or must flush TLB on context
          switch
     Page table
          Typically have page table pointer (register) that must be reloaded on
          context switch


Computer Science, Rutgers             45           CS 519: Operating System Theory
                            Threads & Signals


What happens if kernel wants to signal a process when
all of its threads are blocked?
When there are multiple threads, which thread should
the kernel deliver the signal to?
     OS writes into process control block that a signal should be
     delivered
     Next time any thread from this process is allowed to run, the
     signal is delivered to that thread as part of the context switch
     What happens if kernel needs to deliver multiple signals?




Computer Science, Rutgers          46       CS 519: Operating System Theory
                    Thread Implementation


Kernel-level threads (lightweight processes)
     Kernel sees multiple execution context
     Thread management done by the kernel
User-level threads
     Implemented as a thread library which contains the code for
     thread creation, termination, scheduling and switching
     Kernel sees one execution context and is unaware of thread
     activity
     Can be preemptive or not




Computer Science, Rutgers       47            CS 519: Operating System Theory
      User-Level vs. Kernel-Level Threads


Advantages of user-level threads
     Performance: low-cost thread operations (do not require
     crossing protection domains)
     Flexibility: scheduling can be application specific
     Portability: user-level thread library easy to port
Disadvantages of user-level threads
     If a user-level thread is blocked in the kernel, the entire
     process (all threads of that process) are blocked
     Cannot take advantage of multiprocessing (the kernel assigns
     one process to only one processor)



Computer Science, Rutgers         48          CS 519: Operating System Theory
         User-Level vs. Kernel-Level Threads

user-level                                   kernel-level
threads                                      threads
   threads

   thread
   scheduling                  user

                               kernel
                                                      threads

     process                                         thread                   process
     process                                         scheduling               scheduling
     scheduling

      processor                                       processor



   Computer Science, Rutgers            49             CS 519: Operating System Theory
      User-Level vs. Kernel-Level Threads

No reason why we shouldn’t
have both                               user-level
                                        threads
Most systems now support
kernel threads                          thread
User-level threads are available        scheduling                        user
as linkable libraries
                                                                          kernel
                                        kernel-level
                                        threads

                                        thread                          process
                                        scheduling                      scheduling

                                        processor


Computer Science, Rutgers          50            CS 519: Operating System Theory
                     Threads vs. Processes

Why multiple threads?
     Can’t we use multiple processes to do whatever that is that we
     do with multiple threads?
          Of course, we need to be able to share memory (and other
          resources) between multiple processes …
          But this sharing is already supported – see later in the lecture
     Operations on threads (creation, termination, scheduling, etc..)
     are cheaper than the corresponding operations on processes
          This is because thread operations do not involve manipulations of
          other resources associated with processes
     Inter-thread communication is supported through shared
     memory without kernel intervention
     Why not? Have multiple other resources, why not threads

Computer Science, Rutgers               51           CS 519: Operating System Theory
     Thread/Process Operation Latencies



            Operation       User-level       Kernel     Processes
                             Threads        Threads        (s)
                               (s)           (s)

            Null fork                 34        948          11,300

            Signal-wait               37         441          1,840




Computer Science, Rutgers              52        CS 519: Operating System Theory
Synchronization
                            Synchronization


Problem
     Threads must share data
     Data consistency must be maintained
Example
     Suppose my wife wants to withdraw $5 from our account and I
     want to deposit $10
     What should the balance be after the two transactions have
     been completed?
     What might happen instead if the two transactions were
     executed concurrently?



Computer Science, Rutgers         54       CS 519: Operating System Theory
                     Synchronization (cont)


The balance might be SB – 5
     W reads SB
     I read SB
     I compute SB + 10 and save new balance
     W computes SB – 5 and save new balance
The balance might be SB + 10
     How?
Ensure the orderly execution of cooperating
threads/processes


Computer Science, Rutgers       55        CS 519: Operating System Theory
                            Terminologies


Critical section: a section of code which reads or writes
shared data
Race condition: potential for interleaved execution of a
critical section by multiple threads
     Results are non-deterministic
Mutual exclusion: synchronization mechanism to avoid
race conditions by ensuring exclusive execution of
critical sections
Deadlock: permanent blocking of threads
Starvation: execution but no progress

Computer Science, Rutgers        56     CS 519: Operating System Theory
                      Requirements for ME


No assumptions on hardware: speed, # of processors
Mutual exclusion is maintained – that is, only one thread
at a time can be executing inside a CS
Execution of CS takes a finite time
A thread/process not in CS cannot prevent other
threads/processes to enter the CS
Entering CS cannot de delayed indefinitely: no deadlock
or starvation




Computer Science, Rutgers     57      CS 519: Operating System Theory
                Synchronization Primitives


Most common primitives
     Locks (mutual exclusion)
     Condition variables
     Semaphores
     Monitors
Need
     Semaphores, or
     Locks and condition variables, or
     Monitors



Computer Science, Rutgers         58     CS 519: Operating System Theory
                                    Locks

Mutual exclusion  want to be
the only thread modifying a set
of data items
     Can look at it as exclusive
     access to data items or to a
     piece of code
Have three components:
     Acquire, Release, Waiting




Computer Science, Rutgers            59     CS 519: Operating System Theory
                             Example

public class BankAccount
{
  Lock aLock = new Lock;
  int balance = 0;
   ...
   public void deposit(int amount)      public void withdrawal(int amount)
   {                                    {
         aLock.acquire();                        aLock.acquire();
         balance = balance + amount;             balance = balance - amount;
         aLock.release();                        aLock.release();
   }                                      }
                                        }



Computer Science, Rutgers          60           CS 519: Operating System Theory
    Implementing Locks Inside OS Kernel

From Nachos (with some simplifications)
public class Lock {
  private KThread lockHolder = null;
  private ThreadQueue waitQueue =
           ThreadedKernel.scheduler.newThreadQueue(true);

  public void acquire() {
         KThread thread = KThread.currentThread();   // Get thread object (TCB)
         if (lockHolder != null) {                   // Gotta wait
             waitQueue.waitForAccess(thread);        // Put thread on wait queue
             KThread.sleep();                        // Context switch
         }
         else {
             lockHolder = thread;                    // Got the lock
         }
  }

Computer Science, Rutgers          61          CS 519: Operating System Theory
    Implementing Locks Inside OS Kernel
                  (cont)
    public void release() {
           if ((lockHolder = waitQueue.nextThread()) != null)
               lockHolder.ready();    // Wake up a waiting thread
    }



This implementation is not quite right … what’s missing?




Computer Science, Rutgers             62          CS 519: Operating System Theory
    Implementing Locks Inside OS Kernel
                  (cont)
              public void release() {
                     boolean intStatus = Machine.interrupt().disable();

                    if ((lockHolder = waitQueue.nextThread()) != null)
                        lockHolder.ready();

                    Machine.interrupt().restore(intStatus);
          }




Computer Science, Rutgers                63           CS 519: Operating System Theory
        Implementing Locks At User-Level


Why?
     Expensive to enter the kernel
     Parallel programs on multiprocessor systems
What’s the problem?
     Can’t disable interrupt …
Many software algorithms for mutual exclusion
     See any OS book
     Disadvantages: very difficult to get correct
So what do we do?


Computer Science, Rutgers        64         CS 519: Operating System Theory
        Implementing Locks At User-Level


Simple with a “little bit” of help from the hardware
Atomic read-modify-write instructions
     Test-and-set
          Atomically read a variable and, if the value of the variable is currently
          0, set it to 1
     Fetch-and-increment
     Compare-and-swap




Computer Science, Rutgers               65           CS 519: Operating System Theory
 Atomic Read-Modify-Write Instructions


Test-and-set
     Read a memory location and, if the value is currently 0, set it
     to 1
Fetch-and-increment
     Return the value of of a memory location
     Increment the value by 1 (in memory, not the value returned)
Compare-and-swap
     Compare the value of a memory location with an old value
     If the same, replace with a new value



Computer Science, Rutgers         66         CS 519: Operating System Theory
                            Simple Spin Lock


Test-and-set

          Spin_lock(lock)
          {
                             while (test-and-set(lock) == 0);
          }


          Spin_unlock(lock)
          {
                             lock = 0;
          }


Computer Science, Rutgers                67      CS 519: Operating System Theory
               What To Do While Waiting?


Spinning
     Waiting threads keep testing location until it changes value
     Doesn’t work on uniprocessor system
Blocking
     OS or RT system deschedules waiting threads
Spinning vs. blocking becomes an issue in multiprocessor
systems (with > 1 thread/processor)
What is the main trade-off?
How can we implement a blocking lock?


Computer Science, Rutgers        68         CS 519: Operating System Theory
                                     Deadlock




                            Lock A           Lock B



                              A                 B



Computer Science, Rutgers               69      CS 519: Operating System Theory
                                     Deadlock




                            Lock A           Lock B



                              A                 B



Computer Science, Rutgers               70      CS 519: Operating System Theory
                                     Deadlock




                            Lock A           Lock B



                              A                 B



Computer Science, Rutgers               71      CS 519: Operating System Theory
                            Deadlock (Cont’d)

Deadlock can occur whenever multiple parties are competing for
exclusive access to multiple resources
How can we deal deadlocks?
     Deadlock prevention
          Design a system without one of mutual exclusion, hold and wait, no
          preemption or circular wait (four necessary conditions)
          To prevent circular wait, impose a strict ordering on resources. For instance, if
          need to lock variables A and B, always lock A first, then lock B
     Deadlock avoidance
          Deny requests that may lead to unsafe states (Banker’s algorithm)
          Running the algorithm on all resource requests is expensive
     Deadlock detection and recovery
          Check for circular wait periodically. If circular wait is found, abort all
          deadlocked processes (extreme solution but very common)
          Checking for circular wait is expensive

Computer Science, Rutgers                    72             CS 519: Operating System Theory
                        Condition Variables


A condition variable is always associated with:
     A condition
     A lock
Typically used to wait for the condition to take on a
given value
Three operations:            public class CondVar
                             {
                               public Wait(Lock lock);
                               public Signal();
                               public Broadcast();
                               // ... other stuff
                             }

Computer Science, Rutgers         73         CS 519: Operating System Theory
                        Condition Variables

Wait(Lock lock)
     Release the lock
     Put thread object on wait queue of this CondVar object
     Yield the CPU to another thread
     When waken by the system, reacquire the lock and return
Signal()
     If at least 1 thread is sleeping on cond_var, wake 1 up. Otherwise, no
     effect
     Waking up a thread means changing its state to Ready and moving the
     thread object to the run queue
Broadcast()
     If 1 or more threads are sleeping on cond_var, wake everyone up
     Otherwise, no effect

Computer Science, Rutgers            74          CS 519: Operating System Theory
              Producer/Consumer Example


Imagine a web server with the following architecture:
     One “producer” thread listens for client http requests
     When a request is received, the producer enqueues it on a
     circular request queue with finite capacity (if there is room)
     A number of “consumer” threads services the queue as follows
          Remove the 1st request from the queue (if there is a request)
          Read data from disk to service the request
     How can the producer and consumers synchronize?




Computer Science, Rutgers             75           CS 519: Operating System Theory
                    Producer/Consumer (cont)

          public class SyncQueue
          {
            public boolean IsEmpty();
            public boolean IsFull();
            public boolean Enqueue(Request r);
            public Request Dequeue();

              public LockVar lock = new Lock;
              public CondVar waitForNotEmpty = new CondVar;
              public CondVar waitForNotFull = new CondVar;

              ...
          }



Computer Science, Rutgers          76        CS 519: Operating System Theory
                                 Producer

           public class Producer extends Thread
           {
             private SyncQueue requestQ;
             public Producer(SyncQueue q) {requestQ = q;}
             public void run()
             {
                     // Accept a request from some client.
                     // The request is stored in the object newRequest.

                     requestQ.lock.Acquire();
                     while (requestQ.IsFull()) {
                       waitForNotFull.Wait();
                     }
                     requestQ.Enqueue(newRequest);
                     waitForNotEmpty.Signal();
                     requestQ.lock.Release();
               }
           }
Computer Science, Rutgers               77          CS 519: Operating System Theory
                                   Consumer

                public class Consumer extends Thread
                {
                  private SyncQueue requestQ;
                  public Consumer(SyncQueue q) {requestQ = q;}
                  public void run()
                  {
                          requestQ.lock.Acquire();
                          while (requestQ.IsEmpty()) {
                            waitForNotEmpty.Wait();
                          }
                          Request r = requestQ.Dequeue();
                          waitForNotFull.Signal()
                          requestQ.lock.Release();

                            // Process the request
                    }
                }

Computer Science, Rutgers                  78        CS 519: Operating System Theory
         Implementing Condition Variables


Can you see how to do this from our discussion of how
to implement locks?
You will need to understand how for a later assignment




Computer Science, Rutgers   79     CS 519: Operating System Theory
                            Semaphore

Synchronized counting variables
Formally, a semaphore is comprised of:
      An integer value
      Two operations: P() and V()
P()
      While value = 0, sleep
      Decrement value and return
V()
      Increments value
      If there are any threads sleeping waiting for value to become
      non-zero, wakeup at least 1 thread


Computer Science, Rutgers           80      CS 519: Operating System Theory
                 Implementing Semaphores


Let’s do this together on the board
Can you see how to implement semaphores given locks
and condition variables?
Can you see how to implement locks and condition
variables given semaphores?
Hint: if not, learn how




Computer Science, Rutgers   81        CS 519: Operating System Theory
                            Monitors

Semaphores have a few limitations: unstructured,
difficult to program correctly. Monitors eliminate
these limitations and are as powerful as semaphores
A monitor consists of a software module with one or
more procedures, an initialization sequence, and local
data (can only be accessed by procedures)
Only one process can execute within the monitor at any
one time (mutual exclusion)
Synchronization within the monitor implemented with
condition variables (wait/signal) => one queue per
condition variable


Computer Science, Rutgers      82      CS 519: Operating System Theory
  Lock and Wait-free Synchronization (or
   Mutual Exclusion Considered Harmful)

Problem: Critical sections
     If a process is delayed or halted in a critical section, hard or
     impossible for other processes to make progress
Lock-free (aka non-blocking) concurrent objects
     Some process will complete an operation on the object in a
     finite number of steps
Wait-free concurrent objects
     Each process attempting to perform an operation on the
     concurrent object will complete it in a finite number of steps
Essential difference between these two?


Computer Science, Rutgers         83          CS 519: Operating System Theory
                            Herlihy’s Paper


What’s the point?
     Lock and wait-free synchronization can be very useful for
     building multiprocessor systems; they provide progress
     guarantees
     Building lock and wait-free concurrent objects is HARD, so a
     methodology for implementing these objects is required
     Lock and wait-free synchronization provide guarantees but can
     be rather expensive – lots of copying
M. Greenwald and D. Cheriton. The Synergy between
Non-blocking Synchronization and Operating System
Structure. In Proceedings of OSDI ’96, Oct, 1996.


Computer Science, Rutgers         84       CS 519: Operating System Theory
                      Single Word Protocol


Fetch_and_add_sync(obj: integer, v: integer) returns(integer)
    success: boolean := false
    loop exit when success
       old: integer := obj
       new: integer := old+v
       success := compare_and_swap(obj, old, new)
    end loop
    return old
end Fetch_and_add_sync



                   Lock-free but not wait-free!!


Computer Science, Rutgers       85       CS 519: Operating System Theory
                            Small Objects

Small object: occupies 1 block (or less)
Basic idea of lock-free object implementation
     Allocate a new block
     Copy object to new block, making sure copy is consistent
     Modify copied block, i.e. perform operation on copied block
     Try to atomically replace pointer to old block with new one
Basic idea of wait-free object implementation
     Same as before, except that processes should announce their
     operations in a shared data structure
     Any process in step 3 should perform all previously announced
     operations, not just its own operations


Computer Science, Rutgers        86         CS 519: Operating System Theory
                            Large Objects


I’ll leave for you to read
Basic idea is to make local changes in the data structure
using small object protocol
Complicated but not different than locking: e.g., if you
lock an entire tree to modify some nodes, performance
will go down the drain




Computer Science, Rutgers        87    CS 519: Operating System Theory

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:6
posted:8/3/2011
language:English
pages:87