SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
4 Lock Abstraction
 • Package software/hardware locking into abstract type for general use.
 • Locks are constructed for synchronization or mutual exclusion or both.

4.1 Lock Taxonomy
 • Lock implementation is divided into two general categories: spinning
   and blocking:

             spinning                                  blocking (queueing)

     no yield           yield         mutex     synchronization        semaphore       (others)

                                      owner condition barrier       binary    counting


 • Spinning locks busy wait until an event occurs ⇒ task oscillates
   between ready and running states due to time slicing.
   Except as otherwise noted, the content of this presentation is licensed under the Creative Com-
mons Attribution 2.5 License.
                                              104
105
• Blocking locks do not busy wait, but block until an event occurs ⇒ some
  other mechanism must unblock the waiting task when the event happens.
• Within each category, different kinds of spinning and blocking locks
  exist.

4.2 Spin Lock
• A spin lock is implemented using busy waiting, which spins in a loop
  checking for an event to occur.
• In the examples so far, if a task is busy waiting, it loops until:
  1. A critical section becomes unlocked or an event happens.
  2. The waiting task is preempted (time-slice ends) and put back on the
     ready queue.
  Hence, the CPU is wasting time constantly checking the event.
• To increase efficiency in the uniprocessor case, a task could explicitly
  terminate its time-slice and move back to the ready state after the first
  event check fails.
• The multiprocessor case can have a spinning task terminate its time-slice
  and move back to the ready state after N checks have failed.
106
• Some systems allow the duration of spinning to be adjusted, called an
  adaptive spin-lock.
• Depending on how the spin lock is implemented, it may break rule 5,
  i.e., no bound on service, resulting in starvation of one or more tasks.
• Nevertheless, a spin lock is appropriate and necessary in situations
  where there is no other work to do.

4.2.1 Spin Lock Details
 • µC+ provides a non-yielding spin lock, uSpinLock, and a yielding spin
      +
   lock, uLock.
     class uSpinLock {           class uLock {
        public:                     public:
         uSpinLock(); // open         uLock(unsigned int value = 1);
         void acquire();              void acquire();
         bool tryacquire();           bool tryacquire();
         void release();              void release();
     };                          };
• Both locks are built directly from an atomic hardware instruction.
107
• Locks are either closed (0) or opened (1), and waiting tasks compete to
  acquire the lock after it is released.
• In theory, starvation could occur; in practice, it is seldom a problem.
• uSpinLock is non-preemptive, meaning no other task may execute once
  the lock is acquired, to permit optimizations and additional error
  checking in the µC+ kernel.
                       +
• A non-preemptive lock can only be used for mutual exclusion because
  the task acquiring the lock must release it as no other task may execute.
• Hence, uSpinLock’s constructor does not take a starting state and its
  instances are initialized to open.
• uLock does not have the non-preemptive restriction and can be used for
  both synchronization and mutual exclusion.
• tryacquire makes one attempt to acquire the lock, i.e., it does not wait.
• Any number of releases can be performed on a lock as a release only
  (re)sets the lock to open (1).
• It is not meaningful to read or to assign to a lock variable, or copy a lock
  variable, e.g., pass it as a value parameter.
108
• synchronization
 _Task T1 {                       _Task T2 {
      uLock &lk;                       uLock &lk;
      void main() {                    void main() {
           ...                              ...
           lk.acquire();                    S1
           S2                               lk.release();
           ...                              ...
      }                                }
    public:                          public:
      T1( uLock &lk ) : lk(lk) {}      T2( uLock &lk ) : lk(lk) {}
 };                               };
 void uMain::main() {
      uLock lock(0); // closed
      T1 t1( lock );
      T2 t2( lock );
 }
109
• mutual Exclusion
 _Task T {                       void uMain::main() {
      uLock &lk;                     uLock lock(1); // start open
      void main() {                  T t0( lock ), t1( lock );
           ...                   }
           lk.acquire();
           // critical section
           lk.release();
           ...
           lk.acquire();
           // critical section
           lk.release();
           ...
      }
    public:
      T( uLock &lk ) : lk(lk) {}
 };
  – Does this solution afford maximum concurrency?
  – Are critical sections independent (disjoint) or dependent?
110
4.3 Blocking Locks
• Blocking locks reduce busy waiting by making the task releasing the
  lock do additional work, called cooperation.
• Hence, the responsibility for detecting an open lock is not borne solely
  by an acquiring task, but is shared with the releasing task.

4.3.1 Mutex Lock
 • A mutex lock is used only for mutual exclusion.
 • Tasks waiting on these locks block rather than spin when an event has
   not occurred.
 • Restricting a lock to just mutual exclusion:
   – separates lock usage between synchronization and mutual exclusion
   – permits optimizations and checks as the lock only provides one
     specialized function
 • Mutex locks are divided into two kinds:
   – single acquisition : task that acquired the lock (lock owner) cannot
     acquire it again
111
  – multiple acquisition : lock owner can acquire it multiple times,
    called an owner lock
• Single acquisition cannot handle looping or recursion involving a lock:
     void f() {
         ...
         lock.acquire();
         . . . f();    // recursive call within critical section
         lock.release;
         ...
     }
• Multiple-acquisition locks may require only one release to unlock, or as
  many releases as acquires.
4.3.1.1 Mutex Lock Implementation
 • Implementation of a mutex lock requires a:
    – blocking task to link itself onto a list and yield its time slice
    – releasing task to unblock a waiting task (cooperation)
 • However, operations like adding and removing a node to/from a list are
   not atomic ⇒ mutual exclusion.
112
class MutexLock {
     spinlock lock;                // nonblocking lock
     queue<Task> blocked;          // blocked tasks
     bool inUse;                   // resource being used ?
     Task *owner                   // optional
   public:
     MutexLock() : inUse( false ), owner( NULL ) {}
     void acquire() {
          lock.acquire();
          if ( inUse
                 && owner != thistask() ) { // (optional)
                // add self to lock’s blocked list
                lock.release();    // release before blocking
                // yield
                lock.acquire();    // re-acquire lock
          }
          inUse = true;
          owner = thistask();      // set new owner (optional)
          lock.release();
     }
     void release() {
          lock.acquire();
          owner = NULL;            // no owner (optional)
          if ( ! blocked.empty() ) {
                // remove task from blocked list and make ready
          } else {
                inUse = false;
          }
          lock.release();          // always release lock
     }
};
113
                     mutex lock
                      spin lock         task1         task2        task3
 owner (optional)      task id         blocked       blocked      blocked
        block list

• Which task is scheduled next from the list of blocked tasks?
• Has the busy wait been removed completely?
• An alternative approach is not to release the spin lock if there is a
  waiting task, hence:
  – the mutual exclusion is transfered from the releasing task to the
    unblocking task
  – and the critical section is not bracketed by the spin lock.
4.3.1.2 uOwnerLock Details
 • µC+ only provides an owner lock, uOwnerLock, which subsumes a
      +
   mutex lock.
114
    class uOwnerLock {
       public:
         uOwnerLock();
         void acquire();
         bool tryacquire();
         void release();
    };

• The operations are the same as for uLock but with blocking instead of
  spinning for acquire.
4.3.1.3 Stream Locks
 • Concurrent use of C+ streams can produce unpredictable and
                         +
   undesirable results; e.g., if two tasks execute:
    task1 : cout << "abc " << "def " << endl;
    task2 : cout << "uvw " << "xyz " << endl;
  any of the outputs can appear:
  abc def abc uvw xyz uvw abc xyz def abuvwc dexf uvw abc def
  uvw xyz def                         yz          xyz
115
• µC+ uses owner locks to provide mutual exclusion for streams:
     +
  osacquire for output streams and isacquire for input streams.
• Most common usage is to create as anonymous stream lock for a
  cascaded I/O expression:
    task1 : osacquire( cout ) << "abc " << "def " << endl;
    task2 : osacquire( cout ) << "uvw " << "xyz " << endl;
 constraining the output to two different lines in either order:
    abc def uvw xyz
    uvw xyz abc def
• Multiple I/O statements can be protected using block structure:
    {   // acquire the lock for stream cout for block duration
        osacquire acq( cout ); // named stream lock
        cout << "abc";
        osacquire( cout ) << "uvw " << "xyz " << endl; // OK?
        cout << "def";
    }   // implicitly release the lock when “acq” is deallocated
116
4.3.2 Synchronization Lock
 • A synchronization lock is used solely for synchronization, for the same
   reasons as a mutex lock is used only for mutual exclusion.
 • Often called a condition lock, with wait / signal(notify) for acquire /
   release.
4.3.2.1 Synchronization Lock Implementation
 • Synchronization lock implementation has two forms:
   external locking uses an external mutex lock to protect its state,
   internal locking uses an internal mutex lock to protect its state.
 • Like the mutex lock, the blocking task waits on a list and the releasing
   task performs the necessary cooperation.
 • external locking
117
    class SyncLock {
         Task *list;
       public:
         SyncLock() : list( NULL ) {}
         void acquire( MutexLock &mutexlock ) {
              // add self to lock’s blocked list
              mutexlock.release();
              // yield
         }
         void release() {
              if ( list != NULL ) {
                    // remove task from blocked list and make ready
              }
         }
    };
   – The protecting mutex-lock is passed to acquire to be released by the
     blocking task.
   – Alternatively, the protecting mutex-lock is bound at
     synchronization-lock creation and used implicitly.
• internal locking
118
    class SyncLock {
         spinlock mlock;               // nonblocking lock
         Task *list;                   // blocked tasks
       public:
         SyncLock() : list( NULL ) {}
         void acquire( MutexLock &userlock ) {
              mlock.acquire();
              // add self to task list
              userlock.release();      // release before blocking
              mlock.release();
              // yield
         }
         void release() {
              mlock.acquire();
              if ( list != NULL ) {
                    // remove task from blocked list and make ready
              }
              mlock.release();
         }
    };
• It is still useful (necessary) to be able to unlock an external mutex lock
  before blocking.
• Otherwise, there is a race between releasing the mutex lock and
119
  blocking on the synchronization lock.
4.3.2.2 uCondLock Details
 • µC+ only provides an internal synchronization lock, uCondLock.
      +
    class uCondLock {
       public:
         uCondLock();
         bool empty();
         void wait( uOwnerLock &lock );
         void signal();
         void broadcast();
    };

• empty() returns false if there are tasks blocked on the queue and true
  otherwise.
• wait and signal are used to block a thread on and unblock a thread from
  the queue of a condition, respectively.
• wait atomically blocks the calling task and releases the argument
  owner-lock;
120
• wait re-acquires its argument owner-lock before returning.
• signal releases tasks in FIFO order.
• broadcast is the same as the signal routine, except all waiting tasks are
  unblocked.
 bool done = false;                         _Task T2 {
                                               uOwnerLock &mlk;
  _Task T1 {                                   uCondLock &clk;
     uOwnerLock &mlk;
     uCondLock &clk;                               void main() {
                                                        S1;
        void main() {                                   mlk.acquire();
             mlk.acquire();                             done = true;
             if ( ! done ) clk.wait( mlk );             clk.signal();
             else mlk.release();                        mlk.release();
             S2;                                   }
        }                                        public:
      public:                                      T2( uOwnerLock &mlk,
        T1( uOwnerLock &mlk,                            uCondLock &clk ) :
             uCondLock &clk ) :                         mlk(mlk), clk(clk) {}
             mlk(mlk), clk(clk) {}          };
 };
121
  void uMain::main() {
      uOwnerLock mlk;
      uCondLock clk;
      T1 t1( mlk, clk );
      T2 t2( mlk, clk );
  }

4.3.3 Barrier
 • A barrier is used to repeatedly coordinate a group of tasks performing a
   concurrent operation surrounded by a series of sequential operations.
 • Hence, a barrier is specifically for synchronization and cannot be used to
   build mutual exclusion.
 • Unlike previous synchronization locks, a barrier retains some state about
   the events it manages.
 • Since manipulation of this state requires mutual exclusion, most barriers
   use internal locking.
 • E.g., 3 tasks must execute a section of code in a particular order: S1, S2
   and S3 must all execute before S5, S6 and S7.
122
    X::main() {      Y::main() {         Z::main() {
        ...              ...                 ...
        S1               S2                  S3
        b.block();       b.block();          b.block();
        S5               S6                  S7
        ...              ...                 ...
    }                }                   }
    void uMain::main() {
        uBarrier b( 3 );
        X x( b );
        Y y( b );
        Z z( b );
    }
• The barrier is initialized to control 3 tasks and passed to each task by
  reference (not copied).
• The barrier works by blocking each task at the call to block until all 3
  tasks have reached their call to block on barrier b.
• The last task to call block detects that all the tasks have arrived at the
  barrier, and releases all the tasks (cooperation).
• Hence, all 3 tasks continue execution together after they have all arrived
123
  at the barrier.
• Notice, it is necessary to know in advance the total number of block
  operations executed before the tasks are released.
• Why not use termination synchronization and create new tasks for each
  computation?
• The reason is that the creation and deletion of computation tasks may be
  an unnecessary expense that can be eliminated by using a barrier.

4.3.4 Semaphore
 • A semaphore lock provides synchronization and mutual exclusion
   (Edsger W. Dijkstra).
    semaphore lock(0);    // 0 => closed, 1 => open, default 1
• Like the barrier, a semaphore retains state (counter) to “remember”
  releases.
• names for acquire and release from Dutch terms
• acquire is P
   – passeren ⇒ to pass
124
  – prolagen ⇒ (proberen) to try (verlagen) to decrease
    lock.P();              // wait to enter
 P decrements the semaphore counter and waits if it is zero.
• release is V
   – vrijgeven ⇒ to release
   – verhogen ⇒ to increase
    lock.V();              // release lock
 V increases the counter and unblocks a waiting task (if present).
• When the semaphore counter has only two values (0, 1), it is called a
  binary semaphore.
• Semaphore implementation is similar to mutex/synchronization locks,
  with the counter.
• For example, P and V in conjunction with COBEGIN are as powerful as
  START and WAIT.
• E.g., execute statements so the result is the same as serial execution but
  concurrency is maximized.
125
    S1:   a   :=   1
    S2:   b   :=   2
    S3:   c   :=   a+ b
    S4:   d   :=   2* a
    S5:   e   :=   c+ d
• Analyse which data and code depend on each other.
• I.e., statement S1 and S2 are independent ⇒ can execute in either order
  or at the same time.
• Statement S3 is dependent on S1 and S2 because it uses both results.
• Display dependences graphically in a precedence graph (which is
  different from a process graph).
126
    Sequential    Concurrent
       S1        S1        S2


       S2        S4        S3
T
i
m      S3             S5
e

       S4


       S5
127
    semaphore L1(0), L2(0), L3(0), L4(0);
    COBEGIN
       BEGIN a := 1; V(L1); END;
       BEGIN b := 2; V(L2); END;
       BEGIN P(L1); P(L2); c := a + b; V(L3); END;
       BEGIN P(L1); d := 2 * a; V(L4); END;
       BEGIN P(L3); P(L4); e := c + d; END;
    COEND
• process graph
                                     p
                                         COBEGIN


               p       S1    S2      S3      S4      S5

                                         COEND
                                     p
• Does this solution work?
128
4.3.5 Counting Semaphore
 • Augment the definition of P and V to allow a multi-valued semaphore.
 • Augment V to allow increasing the counter an arbitrary amount.
 • E.g. Three tasks must execute a section of code in a particular order. S2
   and S3 only execute after S1 has completed.
     X::main() {       Y::main() {        Z::main() {
         ...               ...                S1
         s.P();            s.P();             s.V(); // s.V(2)
         S2                S3                 s.V();
         ...               ...                ...
     }                 }                  }

     void uMain::main() {
         uSemaphore s(0);
         X x(s);
         Y y(s);
         Z z(s);
     }
• The problem is that you must know in advance the total number of P’s
129
  on the semaphore (like a barrier).
4.3.5.1 uSemaphore Details
 • µC+ only provides a counting semaphore, uSemaphore, which
      +
   subsumes a binary semaphore.
    class uSemaphore {
       public:
         uSemaphore( unsigned int count = 1 );
         void P();
         bool TryP();
         void V( unsigned int times = 1 );
         int counter() const;
         bool empty() const;
    };

• P decrements the semaphore counter; if the counter is greater than or
  equal to zero, the calling task continues, otherwise it blocks.
• TryP returns true if the semaphore is acquired and false otherwise
  (never blocks).
130
• V wakes up the task blocked for the longest time if there are tasks
  blocked on the semaphore and increments the semaphore counter.
• If V is passed a positive integer value, the semaphore is Ved that many
  times.
• The member routine counter returns the value of the semaphore counter:
   – negative means abs(N) tasks are blocked waiting to acquire the
     semaphore, and the semaphore is locked;
   – zero means no tasks are waiting to acquire the semaphore, and the
     semaphore is locked;
   – positive means the semaphore is unlocked and allows N tasks to
     acquire the semaphore.
• The member routine empty returns false if there are threads blocked on
  the semaphore and true otherwise.

4.4 Semaphore Programming
• Semaphores are used in two distinct ways:
  1. For synchronization, if the semaphore starts at 0 ⇒ waiting for an
     event to occur.
131
  2. For mutual exclusion, if the semaphore starts at 1(N) ⇒ used to
     control a critical section.
• E.g. Unbounded-Buffer Problem
  – Two tasks are communicating unidirectionally through a queue of
     unbounded length.
  – Producer adds results to the end of a queue of unbounded length;
     consumer removes items from the front of the queue unless the queue
     is empty.


      producer                                                 consumer


  – Because they work at different speeds, the producer may get ahead of
    the consumer.
  – The producer never has to wait as the buffer is infinitely long, but the
    consumer may have to wait if the buffer is empty.
  – The queue is shared between the producer/consumer, and a counting
    semaphore controls access.
132
#define QueueSize ∞

int front = 0, back = 0;
int Elements[QueueSize];
uSemaphore signal(0);

void Producer::main() {
    for (;;) {
           // produce an item
           // add to back of queue
           signal.V();
    }
    // produce a stopping value
}
void Consumer::main() {
    for (;;) {
           signal.P();
           // take an item from the front of the queue
       if ( stopping value ? ) break;
           // process or consume the item
    }
}
133
  Is there a problem adding and removing items from the shared queue?
• Is the signal semaphore used for mutual exclusion or synchronization?
• E.g. Bounded-Buffer Problem
   – Two tasks are communicating unidirectionally through a buffer of
     bounded length.
   – Because of the bounded length, the producer may have to wait for the
     consumer to empty it. As well, the buffer may be empty so the
     consumer may have to wait until items are produced.
   – Use counting semaphores to account for the finite length of the shared
     queue.
134
    uSemaphore full(0), empty(QueueSize);
    void Producer::main() {
        for ( . . . ) {
               // produce an item
               empty.P();
               // add to back of queue
               full.V();
        }
        // produce a stopping value
    }
    void Consumer::main() {
        for ( . . . ) {
               full.P();
               // take an item from the front of the queue
           if ( stopping value ? ) break;
               // process or consume the item
               empty.V();
        }
    }
• Does this produce maximum concurrency?
• Can it handle multiple producers/consumers?
135




full   empty
 0      5
136


34

     full   empty
      0      5
      1      4
137


34   13

     full   empty
      0      5
      1      4
      2      3
138


34   13     9

     full       empty
      0          5
      1          4
      2          3
      3          2
139


34   13     9    10

     full       empty
      0          5
      1          4
      2          3
      3          2
      4          1
140


34   13     9    10     -3

     full       empty
      0           5
      1           4
      2           3
      3           2
      4           1
      5           0
141
• E.g. Readers and Writer Problem (Solution 1)
  – Multiple tasks are sharing a resource, and some of them want to read
    the resource and some want to write or modify the resource.
  – Allow multiple concurrent reader tasks simultaneous access, but
    serialize access for writer tasks (a writer may read).
  – A split binary semaphore is a collection of semaphores where at
    most one of the collection has the value 1, i.e., the sum of the
    semaphores is always less than or equal to one.
  – Split binary semaphores can be used to solve complicated
    mutual-exclusion problems by a technique called baton passing.
  – The rules of baton passing are:
    ∗ there is exactly one baton
    ∗ nobody moves in the entry/exit code unless they have it
    ∗ once the baton is released, cannot read/write variables in entry/exit
142




             w




r   r   r                  w     w   w
Readers     baton              Writers
             r
             r
             w      Arrivers
             r
             w
143
uSemaphore entry_q(1);      // split binary semaphore
uSemaphore read_q(0), write_q(0);
int r_cnt = 0, w_cnt = 0;   // auxiliary
int r_del = 0, w_del = 0;

void Reader::main() {
    entry_q.P();               // entry protocol
    if ( w_cnt > 0 ) {
          r_del += 1; entry_q.V(); read_q.P();
    }
    r_cnt += 1;
    if ( r_del > 0 ) {
          r_del -= 1; read_q.V(); // pass baton
    } else {
          entry_q.V();
    }

    yield();                   // pretend to read

    entry_q.P();               // exit protocol
    r_cnt -= 1;
    if ( r_cnt == 0 && w_del > 0 ) {
          w_del -= 1; write_q.V(); // pass baton
    } else {
          entry_q.V();
    }
}
144
      void Writer::main() {
          entry_q.P();               // entry protocol
          if ( r_cnt > 0 | | w_cnt > 0 ) {
                w_del += 1; entry_q.V(); write_q.P();
          }
          w_cnt += 1;
          entry_q.V();

          yield();                   // pretend to write

          entry_q.P();               // exit protocol
          w_cnt -= 1;
          if ( r_del > 0 ) {
                r_del -= 1; read_q.V(); // pass baton
          } else if ( w_del > 0 ) {
                w_del -= 1; write_q.V(); // pass baton
          } else {
                entry_q.V();
          }
      }
  – Problem: continuous stream of readers ⇒ no writer can get in, so
    starvation.
• E.g. Readers and Writer Problem (Solution 2)
145
– Give writers priority and make the readers wait.
– Change entry protocol for reader to the following:
    entry_q.P();               // entry protocol
    if ( w_cnt > 0 | | w_del > 0 ) {
          r_del += 1; entry_q.V(); read_q.P();
    }
    r_cnt += 1;
    if ( r_del > 0 ) {
          r_del -= 1; read_q.V();
    } else {
          entry_q.V();
    }
– Also, change writer’s exit protocol to favour writers:
    entry_q.P();              // exit protocol
    w_cnt -= 1;
    if ( w_del > 0 ) {        // check writers first
         w_del -= 1; write_q.V();
    } else if ( r_del > 0 ) {
         r_del -= 1; read_q.V();
    } else {
         entry_q.V();
    }
146
  – Now readers can starve.
• E.g. Readers and Writer Problem (Solution 3)
                                           w
                                          12:30




                 r        r                                  w
                2:00     1:00            baton              1:30
  – Readers wait if there is a waiting writer, all readers are started after a
    writer (i.e. alternate group of readers then a writer)
  – There is a problem: staleness/freshness.
• E.g. Readers and Writer Problem (Solution 4)
  – Service readers and writers in a first-in first-out (FIFO) fashion, but
    allow multiple concurrent readers.
  – Must put readers and writers on same condition variable to maintain
    temporal order but then lose what kind of task.
147
– Maintain a shadow list to know the kind of task is waiting at front of
  condition variable:
               semaphore     t0 → t1 → t2 → t3 → t4 → . . .
               shadow-list w → r → w → r → r → . . .

Mais conteúdo relacionado

Mais procurados

Grand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CGrand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CPavel Albitsky
 
Dalvik Source Code Reading
Dalvik Source Code ReadingDalvik Source Code Reading
Dalvik Source Code Readingkishima7
 
Arc of developer part1
Arc of developer part1Arc of developer part1
Arc of developer part1Junpei Wada
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCanSecWest
 
Vert.x v3 - high performance polyglot application toolkit
Vert.x v3 - high performance  polyglot application toolkitVert.x v3 - high performance  polyglot application toolkit
Vert.x v3 - high performance polyglot application toolkitSages
 
CSharp for Unity Day2
CSharp for Unity Day2CSharp for Unity Day2
CSharp for Unity Day2Duong Thanh
 
Bucks County Tech Meetup: node.js introduction
Bucks County Tech Meetup: node.js introductionBucks County Tech Meetup: node.js introduction
Bucks County Tech Meetup: node.js introductiondshkolnikov
 
20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzleComputer Science Club
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.UA Mobile
 
JavaScript and AJAX
JavaScript and AJAXJavaScript and AJAX
JavaScript and AJAXFrane Bandov
 
ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)Makoto Yamazaki
 
ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)Makoto Yamazaki
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Alexey Fyodorov
 
Async Best Practices
Async Best PracticesAsync Best Practices
Async Best PracticesLluis Franco
 
Java concurrency in practice
Java concurrency in practiceJava concurrency in practice
Java concurrency in practiceMikalai Alimenkou
 
BlueHat v18 || A mitigation for kernel toctou vulnerabilities
BlueHat v18 || A mitigation for kernel toctou vulnerabilitiesBlueHat v18 || A mitigation for kernel toctou vulnerabilities
BlueHat v18 || A mitigation for kernel toctou vulnerabilitiesBlueHat Security Conference
 
Sequence detector for "111"
Sequence detector for "111"Sequence detector for "111"
Sequence detector for "111"Omkar Rane
 

Mais procurados (20)

Grand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-CGrand Central Dispatch in Objective-C
Grand Central Dispatch in Objective-C
 
Dalvik Source Code Reading
Dalvik Source Code ReadingDalvik Source Code Reading
Dalvik Source Code Reading
 
Arc of developer part1
Arc of developer part1Arc of developer part1
Arc of developer part1
 
Csw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemesCsw2016 gawlik bypassing_differentdefenseschemes
Csw2016 gawlik bypassing_differentdefenseschemes
 
Vert.x v3 - high performance polyglot application toolkit
Vert.x v3 - high performance  polyglot application toolkitVert.x v3 - high performance  polyglot application toolkit
Vert.x v3 - high performance polyglot application toolkit
 
Twisted
TwistedTwisted
Twisted
 
Sysprog 14
Sysprog 14Sysprog 14
Sysprog 14
 
CSharp for Unity Day2
CSharp for Unity Day2CSharp for Unity Day2
CSharp for Unity Day2
 
Bucks County Tech Meetup: node.js introduction
Bucks County Tech Meetup: node.js introductionBucks County Tech Meetup: node.js introduction
Bucks County Tech Meetup: node.js introduction
 
20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle20101017 program analysis_for_security_livshits_lecture04_nozzle
20101017 program analysis_for_security_livshits_lecture04_nozzle
 
Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.Coroutines in Kotlin. UA Mobile 2017.
Coroutines in Kotlin. UA Mobile 2017.
 
JavaScript and AJAX
JavaScript and AJAXJavaScript and AJAX
JavaScript and AJAX
 
Coroutines in Kotlin
Coroutines in KotlinCoroutines in Kotlin
Coroutines in Kotlin
 
ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)
 
ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)ぐだ生 Java入門第ニ回(synchronized and lock)
ぐだ生 Java入門第ニ回(synchronized and lock)
 
Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)Counter Wars (JEEConf 2016)
Counter Wars (JEEConf 2016)
 
Async Best Practices
Async Best PracticesAsync Best Practices
Async Best Practices
 
Java concurrency in practice
Java concurrency in practiceJava concurrency in practice
Java concurrency in practice
 
BlueHat v18 || A mitigation for kernel toctou vulnerabilities
BlueHat v18 || A mitigation for kernel toctou vulnerabilitiesBlueHat v18 || A mitigation for kernel toctou vulnerabilities
BlueHat v18 || A mitigation for kernel toctou vulnerabilities
 
Sequence detector for "111"
Sequence detector for "111"Sequence detector for "111"
Sequence detector for "111"
 

Semelhante a Locks (Concurrency)

semaphore & mutex.pdf
semaphore & mutex.pdfsemaphore & mutex.pdf
semaphore & mutex.pdfAdrian Huang
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Roman Elizarov
 
Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)Sneeker Yeh
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)Sri Prasanna
 
Understanding PostgreSQL LW Locks
Understanding PostgreSQL LW LocksUnderstanding PostgreSQL LW Locks
Understanding PostgreSQL LW LocksJignesh Shah
 
Cancellation in coroutines
Cancellation in coroutinesCancellation in coroutines
Cancellation in coroutinesAbdalla Adel
 
Synchronization problem with threads
Synchronization problem with threadsSynchronization problem with threads
Synchronization problem with threadsSyed Zaid Irshad
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waitingRoman Elizarov
 
Distributed Locking in Kubernetes
Distributed Locking in KubernetesDistributed Locking in Kubernetes
Distributed Locking in KubernetesRafał Leszko
 
Theorical 1
Theorical 1Theorical 1
Theorical 1everblut
 
Teorical 1
Teorical 1Teorical 1
Teorical 1everblut
 
Much Ado About Blocking: Wait/Wakke in the Linux Kernel
Much Ado About Blocking: Wait/Wakke in the Linux KernelMuch Ado About Blocking: Wait/Wakke in the Linux Kernel
Much Ado About Blocking: Wait/Wakke in the Linux KernelDavidlohr Bueso
 
Let's Talk Locks!
Let's Talk Locks!Let's Talk Locks!
Let's Talk Locks!C4Media
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsCarol McDonald
 
Theorical 1
Theorical 1Theorical 1
Theorical 1everblut
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Artur Latoszewski
 

Semelhante a Locks (Concurrency) (20)

semaphore & mutex.pdf
semaphore & mutex.pdfsemaphore & mutex.pdf
semaphore & mutex.pdf
 
Wait for your fortune without Blocking!
Wait for your fortune without Blocking!Wait for your fortune without Blocking!
Wait for your fortune without Blocking!
 
Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)Dead Lock Analysis of spin_lock() in Linux Kernel (english)
Dead Lock Analysis of spin_lock() in Linux Kernel (english)
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
 
Understanding PostgreSQL LW Locks
Understanding PostgreSQL LW LocksUnderstanding PostgreSQL LW Locks
Understanding PostgreSQL LW Locks
 
Cancellation in coroutines
Cancellation in coroutinesCancellation in coroutines
Cancellation in coroutines
 
Synchronization problem with threads
Synchronization problem with threadsSynchronization problem with threads
Synchronization problem with threads
 
Non blocking programming and waiting
Non blocking programming and waitingNon blocking programming and waiting
Non blocking programming and waiting
 
Lect04
Lect04Lect04
Lect04
 
Distributed Locking in Kubernetes
Distributed Locking in KubernetesDistributed Locking in Kubernetes
Distributed Locking in Kubernetes
 
Theorical 1
Theorical 1Theorical 1
Theorical 1
 
Teorical 1
Teorical 1Teorical 1
Teorical 1
 
Much Ado About Blocking: Wait/Wakke in the Linux Kernel
Much Ado About Blocking: Wait/Wakke in the Linux KernelMuch Ado About Blocking: Wait/Wakke in the Linux Kernel
Much Ado About Blocking: Wait/Wakke in the Linux Kernel
 
Let's Talk Locks!
Let's Talk Locks!Let's Talk Locks!
Let's Talk Locks!
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
 
Theorical 1
Theorical 1Theorical 1
Theorical 1
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?
 
Unbounded
UnboundedUnbounded
Unbounded
 
Unbounded
UnboundedUnbounded
Unbounded
 
Kernel
KernelKernel
Kernel
 

Mais de Sri Prasanna

Mais de Sri Prasanna (20)

Qr codes para tech radar
Qr codes para tech radarQr codes para tech radar
Qr codes para tech radar
 
Qr codes para tech radar 2
Qr codes para tech radar 2Qr codes para tech radar 2
Qr codes para tech radar 2
 
Test
TestTest
Test
 
Test
TestTest
Test
 
assds
assdsassds
assds
 
assds
assdsassds
assds
 
asdsa
asdsaasdsa
asdsa
 
dsd
dsddsd
dsd
 
About stacks
About stacksAbout stacks
About stacks
 
About Stacks
About  StacksAbout  Stacks
About Stacks
 
About Stacks
About  StacksAbout  Stacks
About Stacks
 
About Stacks
About  StacksAbout  Stacks
About Stacks
 
About Stacks
About  StacksAbout  Stacks
About Stacks
 
About Stacks
About  StacksAbout  Stacks
About Stacks
 
About Stacks
About StacksAbout Stacks
About Stacks
 
About Stacks
About StacksAbout Stacks
About Stacks
 
Network and distributed systems
Network and distributed systemsNetwork and distributed systems
Network and distributed systems
 
Introduction & Parellelization on large scale clusters
Introduction & Parellelization on large scale clustersIntroduction & Parellelization on large scale clusters
Introduction & Parellelization on large scale clusters
 
Mapreduce: Theory and implementation
Mapreduce: Theory and implementationMapreduce: Theory and implementation
Mapreduce: Theory and implementation
 
Other distributed systems
Other distributed systemsOther distributed systems
Other distributed systems
 

Último

Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...lizamodels9
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.Aaiza Hassan
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaShree Krishna Exports
 
Event mailer assignment progress report .pdf
Event mailer assignment progress report .pdfEvent mailer assignment progress report .pdf
Event mailer assignment progress report .pdftbatkhuu1
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxAndy Lambert
 
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 DelhiCall Girls in Delhi
 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsMichael W. Hawkins
 
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...anilsa9823
 
GD Birla and his contribution in management
GD Birla and his contribution in managementGD Birla and his contribution in management
GD Birla and his contribution in managementchhavia330
 
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableCall Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableDipal Arora
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageMatteo Carbone
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayNZSG
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation SlidesKeppelCorporation
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyEthan lee
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Lviv Startup Club
 
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Tina Ji
 
Progress Report - Oracle Database Analyst Summit
Progress  Report - Oracle Database Analyst SummitProgress  Report - Oracle Database Analyst Summit
Progress Report - Oracle Database Analyst SummitHolger Mueller
 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Delhi Call girls
 

Último (20)

Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
Call Girls In DLf Gurgaon ➥99902@11544 ( Best price)100% Genuine Escort In 24...
 
M.C Lodges -- Guest House in Jhang.
M.C Lodges --  Guest House in Jhang.M.C Lodges --  Guest House in Jhang.
M.C Lodges -- Guest House in Jhang.
 
Best Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in IndiaBest Basmati Rice Manufacturers in India
Best Basmati Rice Manufacturers in India
 
Event mailer assignment progress report .pdf
Event mailer assignment progress report .pdfEvent mailer assignment progress report .pdf
Event mailer assignment progress report .pdf
 
Monthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptxMonthly Social Media Update April 2024 pptx.pptx
Monthly Social Media Update April 2024 pptx.pptx
 
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
9599632723 Top Call Girls in Delhi at your Door Step Available 24x7 Delhi
 
HONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael HawkinsHONOR Veterans Event Keynote by Michael Hawkins
HONOR Veterans Event Keynote by Michael Hawkins
 
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
Lucknow 💋 Escorts in Lucknow - 450+ Call Girl Cash Payment 8923113531 Neha Th...
 
GD Birla and his contribution in management
GD Birla and his contribution in managementGD Birla and his contribution in management
GD Birla and his contribution in management
 
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service AvailableCall Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
Call Girls Pune Just Call 9907093804 Top Class Call Girl Service Available
 
Insurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usageInsurers' journeys to build a mastery in the IoT usage
Insurers' journeys to build a mastery in the IoT usage
 
It will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 MayIt will be International Nurses' Day on 12 May
It will be International Nurses' Day on 12 May
 
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
Keppel Ltd. 1Q 2024 Business Update  Presentation SlidesKeppel Ltd. 1Q 2024 Business Update  Presentation Slides
Keppel Ltd. 1Q 2024 Business Update Presentation Slides
 
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case studyThe Coffee Bean & Tea Leaf(CBTL), Business strategy case study
The Coffee Bean & Tea Leaf(CBTL), Business strategy case study
 
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
Yaroslav Rozhankivskyy: Три складові і три передумови максимальної продуктивн...
 
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
Russian Faridabad Call Girls(Badarpur) : ☎ 8168257667, @4999
 
Progress Report - Oracle Database Analyst Summit
Progress  Report - Oracle Database Analyst SummitProgress  Report - Oracle Database Analyst Summit
Progress Report - Oracle Database Analyst Summit
 
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
Best VIP Call Girls Noida Sector 40 Call Me: 8448380779
 
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
VVVIP Call Girls In Greater Kailash ➡️ Delhi ➡️ 9999965857 🚀 No Advance 24HRS...
 
Nepali Escort Girl Kakori \ 9548273370 Indian Call Girls Service Lucknow ₹,9517
Nepali Escort Girl Kakori \ 9548273370 Indian Call Girls Service Lucknow ₹,9517Nepali Escort Girl Kakori \ 9548273370 Indian Call Girls Service Lucknow ₹,9517
Nepali Escort Girl Kakori \ 9548273370 Indian Call Girls Service Lucknow ₹,9517
 

Locks (Concurrency)

  • 1. 4 Lock Abstraction • Package software/hardware locking into abstract type for general use. • Locks are constructed for synchronization or mutual exclusion or both. 4.1 Lock Taxonomy • Lock implementation is divided into two general categories: spinning and blocking: spinning blocking (queueing) no yield yield mutex synchronization semaphore (others) owner condition barrier binary counting • Spinning locks busy wait until an event occurs ⇒ task oscillates between ready and running states due to time slicing. Except as otherwise noted, the content of this presentation is licensed under the Creative Com- mons Attribution 2.5 License. 104
  • 2. 105 • Blocking locks do not busy wait, but block until an event occurs ⇒ some other mechanism must unblock the waiting task when the event happens. • Within each category, different kinds of spinning and blocking locks exist. 4.2 Spin Lock • A spin lock is implemented using busy waiting, which spins in a loop checking for an event to occur. • In the examples so far, if a task is busy waiting, it loops until: 1. A critical section becomes unlocked or an event happens. 2. The waiting task is preempted (time-slice ends) and put back on the ready queue. Hence, the CPU is wasting time constantly checking the event. • To increase efficiency in the uniprocessor case, a task could explicitly terminate its time-slice and move back to the ready state after the first event check fails. • The multiprocessor case can have a spinning task terminate its time-slice and move back to the ready state after N checks have failed.
  • 3. 106 • Some systems allow the duration of spinning to be adjusted, called an adaptive spin-lock. • Depending on how the spin lock is implemented, it may break rule 5, i.e., no bound on service, resulting in starvation of one or more tasks. • Nevertheless, a spin lock is appropriate and necessary in situations where there is no other work to do. 4.2.1 Spin Lock Details • µC+ provides a non-yielding spin lock, uSpinLock, and a yielding spin + lock, uLock. class uSpinLock { class uLock { public: public: uSpinLock(); // open uLock(unsigned int value = 1); void acquire(); void acquire(); bool tryacquire(); bool tryacquire(); void release(); void release(); }; }; • Both locks are built directly from an atomic hardware instruction.
  • 4. 107 • Locks are either closed (0) or opened (1), and waiting tasks compete to acquire the lock after it is released. • In theory, starvation could occur; in practice, it is seldom a problem. • uSpinLock is non-preemptive, meaning no other task may execute once the lock is acquired, to permit optimizations and additional error checking in the µC+ kernel. + • A non-preemptive lock can only be used for mutual exclusion because the task acquiring the lock must release it as no other task may execute. • Hence, uSpinLock’s constructor does not take a starting state and its instances are initialized to open. • uLock does not have the non-preemptive restriction and can be used for both synchronization and mutual exclusion. • tryacquire makes one attempt to acquire the lock, i.e., it does not wait. • Any number of releases can be performed on a lock as a release only (re)sets the lock to open (1). • It is not meaningful to read or to assign to a lock variable, or copy a lock variable, e.g., pass it as a value parameter.
  • 5. 108 • synchronization _Task T1 { _Task T2 { uLock &lk; uLock &lk; void main() { void main() { ... ... lk.acquire(); S1 S2 lk.release(); ... ... } } public: public: T1( uLock &lk ) : lk(lk) {} T2( uLock &lk ) : lk(lk) {} }; }; void uMain::main() { uLock lock(0); // closed T1 t1( lock ); T2 t2( lock ); }
  • 6. 109 • mutual Exclusion _Task T { void uMain::main() { uLock &lk; uLock lock(1); // start open void main() { T t0( lock ), t1( lock ); ... } lk.acquire(); // critical section lk.release(); ... lk.acquire(); // critical section lk.release(); ... } public: T( uLock &lk ) : lk(lk) {} }; – Does this solution afford maximum concurrency? – Are critical sections independent (disjoint) or dependent?
  • 7. 110 4.3 Blocking Locks • Blocking locks reduce busy waiting by making the task releasing the lock do additional work, called cooperation. • Hence, the responsibility for detecting an open lock is not borne solely by an acquiring task, but is shared with the releasing task. 4.3.1 Mutex Lock • A mutex lock is used only for mutual exclusion. • Tasks waiting on these locks block rather than spin when an event has not occurred. • Restricting a lock to just mutual exclusion: – separates lock usage between synchronization and mutual exclusion – permits optimizations and checks as the lock only provides one specialized function • Mutex locks are divided into two kinds: – single acquisition : task that acquired the lock (lock owner) cannot acquire it again
  • 8. 111 – multiple acquisition : lock owner can acquire it multiple times, called an owner lock • Single acquisition cannot handle looping or recursion involving a lock: void f() { ... lock.acquire(); . . . f(); // recursive call within critical section lock.release; ... } • Multiple-acquisition locks may require only one release to unlock, or as many releases as acquires. 4.3.1.1 Mutex Lock Implementation • Implementation of a mutex lock requires a: – blocking task to link itself onto a list and yield its time slice – releasing task to unblock a waiting task (cooperation) • However, operations like adding and removing a node to/from a list are not atomic ⇒ mutual exclusion.
  • 9. 112 class MutexLock { spinlock lock; // nonblocking lock queue<Task> blocked; // blocked tasks bool inUse; // resource being used ? Task *owner // optional public: MutexLock() : inUse( false ), owner( NULL ) {} void acquire() { lock.acquire(); if ( inUse && owner != thistask() ) { // (optional) // add self to lock’s blocked list lock.release(); // release before blocking // yield lock.acquire(); // re-acquire lock } inUse = true; owner = thistask(); // set new owner (optional) lock.release(); } void release() { lock.acquire(); owner = NULL; // no owner (optional) if ( ! blocked.empty() ) { // remove task from blocked list and make ready } else { inUse = false; } lock.release(); // always release lock } };
  • 10. 113 mutex lock spin lock task1 task2 task3 owner (optional) task id blocked blocked blocked block list • Which task is scheduled next from the list of blocked tasks? • Has the busy wait been removed completely? • An alternative approach is not to release the spin lock if there is a waiting task, hence: – the mutual exclusion is transfered from the releasing task to the unblocking task – and the critical section is not bracketed by the spin lock. 4.3.1.2 uOwnerLock Details • µC+ only provides an owner lock, uOwnerLock, which subsumes a + mutex lock.
  • 11. 114 class uOwnerLock { public: uOwnerLock(); void acquire(); bool tryacquire(); void release(); }; • The operations are the same as for uLock but with blocking instead of spinning for acquire. 4.3.1.3 Stream Locks • Concurrent use of C+ streams can produce unpredictable and + undesirable results; e.g., if two tasks execute: task1 : cout << "abc " << "def " << endl; task2 : cout << "uvw " << "xyz " << endl; any of the outputs can appear: abc def abc uvw xyz uvw abc xyz def abuvwc dexf uvw abc def uvw xyz def yz xyz
  • 12. 115 • µC+ uses owner locks to provide mutual exclusion for streams: + osacquire for output streams and isacquire for input streams. • Most common usage is to create as anonymous stream lock for a cascaded I/O expression: task1 : osacquire( cout ) << "abc " << "def " << endl; task2 : osacquire( cout ) << "uvw " << "xyz " << endl; constraining the output to two different lines in either order: abc def uvw xyz uvw xyz abc def • Multiple I/O statements can be protected using block structure: { // acquire the lock for stream cout for block duration osacquire acq( cout ); // named stream lock cout << "abc"; osacquire( cout ) << "uvw " << "xyz " << endl; // OK? cout << "def"; } // implicitly release the lock when “acq” is deallocated
  • 13. 116 4.3.2 Synchronization Lock • A synchronization lock is used solely for synchronization, for the same reasons as a mutex lock is used only for mutual exclusion. • Often called a condition lock, with wait / signal(notify) for acquire / release. 4.3.2.1 Synchronization Lock Implementation • Synchronization lock implementation has two forms: external locking uses an external mutex lock to protect its state, internal locking uses an internal mutex lock to protect its state. • Like the mutex lock, the blocking task waits on a list and the releasing task performs the necessary cooperation. • external locking
  • 14. 117 class SyncLock { Task *list; public: SyncLock() : list( NULL ) {} void acquire( MutexLock &mutexlock ) { // add self to lock’s blocked list mutexlock.release(); // yield } void release() { if ( list != NULL ) { // remove task from blocked list and make ready } } }; – The protecting mutex-lock is passed to acquire to be released by the blocking task. – Alternatively, the protecting mutex-lock is bound at synchronization-lock creation and used implicitly. • internal locking
  • 15. 118 class SyncLock { spinlock mlock; // nonblocking lock Task *list; // blocked tasks public: SyncLock() : list( NULL ) {} void acquire( MutexLock &userlock ) { mlock.acquire(); // add self to task list userlock.release(); // release before blocking mlock.release(); // yield } void release() { mlock.acquire(); if ( list != NULL ) { // remove task from blocked list and make ready } mlock.release(); } }; • It is still useful (necessary) to be able to unlock an external mutex lock before blocking. • Otherwise, there is a race between releasing the mutex lock and
  • 16. 119 blocking on the synchronization lock. 4.3.2.2 uCondLock Details • µC+ only provides an internal synchronization lock, uCondLock. + class uCondLock { public: uCondLock(); bool empty(); void wait( uOwnerLock &lock ); void signal(); void broadcast(); }; • empty() returns false if there are tasks blocked on the queue and true otherwise. • wait and signal are used to block a thread on and unblock a thread from the queue of a condition, respectively. • wait atomically blocks the calling task and releases the argument owner-lock;
  • 17. 120 • wait re-acquires its argument owner-lock before returning. • signal releases tasks in FIFO order. • broadcast is the same as the signal routine, except all waiting tasks are unblocked. bool done = false; _Task T2 { uOwnerLock &mlk; _Task T1 { uCondLock &clk; uOwnerLock &mlk; uCondLock &clk; void main() { S1; void main() { mlk.acquire(); mlk.acquire(); done = true; if ( ! done ) clk.wait( mlk ); clk.signal(); else mlk.release(); mlk.release(); S2; } } public: public: T2( uOwnerLock &mlk, T1( uOwnerLock &mlk, uCondLock &clk ) : uCondLock &clk ) : mlk(mlk), clk(clk) {} mlk(mlk), clk(clk) {} }; };
  • 18. 121 void uMain::main() { uOwnerLock mlk; uCondLock clk; T1 t1( mlk, clk ); T2 t2( mlk, clk ); } 4.3.3 Barrier • A barrier is used to repeatedly coordinate a group of tasks performing a concurrent operation surrounded by a series of sequential operations. • Hence, a barrier is specifically for synchronization and cannot be used to build mutual exclusion. • Unlike previous synchronization locks, a barrier retains some state about the events it manages. • Since manipulation of this state requires mutual exclusion, most barriers use internal locking. • E.g., 3 tasks must execute a section of code in a particular order: S1, S2 and S3 must all execute before S5, S6 and S7.
  • 19. 122 X::main() { Y::main() { Z::main() { ... ... ... S1 S2 S3 b.block(); b.block(); b.block(); S5 S6 S7 ... ... ... } } } void uMain::main() { uBarrier b( 3 ); X x( b ); Y y( b ); Z z( b ); } • The barrier is initialized to control 3 tasks and passed to each task by reference (not copied). • The barrier works by blocking each task at the call to block until all 3 tasks have reached their call to block on barrier b. • The last task to call block detects that all the tasks have arrived at the barrier, and releases all the tasks (cooperation). • Hence, all 3 tasks continue execution together after they have all arrived
  • 20. 123 at the barrier. • Notice, it is necessary to know in advance the total number of block operations executed before the tasks are released. • Why not use termination synchronization and create new tasks for each computation? • The reason is that the creation and deletion of computation tasks may be an unnecessary expense that can be eliminated by using a barrier. 4.3.4 Semaphore • A semaphore lock provides synchronization and mutual exclusion (Edsger W. Dijkstra). semaphore lock(0); // 0 => closed, 1 => open, default 1 • Like the barrier, a semaphore retains state (counter) to “remember” releases. • names for acquire and release from Dutch terms • acquire is P – passeren ⇒ to pass
  • 21. 124 – prolagen ⇒ (proberen) to try (verlagen) to decrease lock.P(); // wait to enter P decrements the semaphore counter and waits if it is zero. • release is V – vrijgeven ⇒ to release – verhogen ⇒ to increase lock.V(); // release lock V increases the counter and unblocks a waiting task (if present). • When the semaphore counter has only two values (0, 1), it is called a binary semaphore. • Semaphore implementation is similar to mutex/synchronization locks, with the counter. • For example, P and V in conjunction with COBEGIN are as powerful as START and WAIT. • E.g., execute statements so the result is the same as serial execution but concurrency is maximized.
  • 22. 125 S1: a := 1 S2: b := 2 S3: c := a+ b S4: d := 2* a S5: e := c+ d • Analyse which data and code depend on each other. • I.e., statement S1 and S2 are independent ⇒ can execute in either order or at the same time. • Statement S3 is dependent on S1 and S2 because it uses both results. • Display dependences graphically in a precedence graph (which is different from a process graph).
  • 23. 126 Sequential Concurrent S1 S1 S2 S2 S4 S3 T i m S3 S5 e S4 S5
  • 24. 127 semaphore L1(0), L2(0), L3(0), L4(0); COBEGIN BEGIN a := 1; V(L1); END; BEGIN b := 2; V(L2); END; BEGIN P(L1); P(L2); c := a + b; V(L3); END; BEGIN P(L1); d := 2 * a; V(L4); END; BEGIN P(L3); P(L4); e := c + d; END; COEND • process graph p COBEGIN p S1 S2 S3 S4 S5 COEND p • Does this solution work?
  • 25. 128 4.3.5 Counting Semaphore • Augment the definition of P and V to allow a multi-valued semaphore. • Augment V to allow increasing the counter an arbitrary amount. • E.g. Three tasks must execute a section of code in a particular order. S2 and S3 only execute after S1 has completed. X::main() { Y::main() { Z::main() { ... ... S1 s.P(); s.P(); s.V(); // s.V(2) S2 S3 s.V(); ... ... ... } } } void uMain::main() { uSemaphore s(0); X x(s); Y y(s); Z z(s); } • The problem is that you must know in advance the total number of P’s
  • 26. 129 on the semaphore (like a barrier). 4.3.5.1 uSemaphore Details • µC+ only provides a counting semaphore, uSemaphore, which + subsumes a binary semaphore. class uSemaphore { public: uSemaphore( unsigned int count = 1 ); void P(); bool TryP(); void V( unsigned int times = 1 ); int counter() const; bool empty() const; }; • P decrements the semaphore counter; if the counter is greater than or equal to zero, the calling task continues, otherwise it blocks. • TryP returns true if the semaphore is acquired and false otherwise (never blocks).
  • 27. 130 • V wakes up the task blocked for the longest time if there are tasks blocked on the semaphore and increments the semaphore counter. • If V is passed a positive integer value, the semaphore is Ved that many times. • The member routine counter returns the value of the semaphore counter: – negative means abs(N) tasks are blocked waiting to acquire the semaphore, and the semaphore is locked; – zero means no tasks are waiting to acquire the semaphore, and the semaphore is locked; – positive means the semaphore is unlocked and allows N tasks to acquire the semaphore. • The member routine empty returns false if there are threads blocked on the semaphore and true otherwise. 4.4 Semaphore Programming • Semaphores are used in two distinct ways: 1. For synchronization, if the semaphore starts at 0 ⇒ waiting for an event to occur.
  • 28. 131 2. For mutual exclusion, if the semaphore starts at 1(N) ⇒ used to control a critical section. • E.g. Unbounded-Buffer Problem – Two tasks are communicating unidirectionally through a queue of unbounded length. – Producer adds results to the end of a queue of unbounded length; consumer removes items from the front of the queue unless the queue is empty. producer consumer – Because they work at different speeds, the producer may get ahead of the consumer. – The producer never has to wait as the buffer is infinitely long, but the consumer may have to wait if the buffer is empty. – The queue is shared between the producer/consumer, and a counting semaphore controls access.
  • 29. 132 #define QueueSize ∞ int front = 0, back = 0; int Elements[QueueSize]; uSemaphore signal(0); void Producer::main() { for (;;) { // produce an item // add to back of queue signal.V(); } // produce a stopping value } void Consumer::main() { for (;;) { signal.P(); // take an item from the front of the queue if ( stopping value ? ) break; // process or consume the item } }
  • 30. 133 Is there a problem adding and removing items from the shared queue? • Is the signal semaphore used for mutual exclusion or synchronization? • E.g. Bounded-Buffer Problem – Two tasks are communicating unidirectionally through a buffer of bounded length. – Because of the bounded length, the producer may have to wait for the consumer to empty it. As well, the buffer may be empty so the consumer may have to wait until items are produced. – Use counting semaphores to account for the finite length of the shared queue.
  • 31. 134 uSemaphore full(0), empty(QueueSize); void Producer::main() { for ( . . . ) { // produce an item empty.P(); // add to back of queue full.V(); } // produce a stopping value } void Consumer::main() { for ( . . . ) { full.P(); // take an item from the front of the queue if ( stopping value ? ) break; // process or consume the item empty.V(); } } • Does this produce maximum concurrency? • Can it handle multiple producers/consumers?
  • 32. 135 full empty 0 5
  • 33. 136 34 full empty 0 5 1 4
  • 34. 137 34 13 full empty 0 5 1 4 2 3
  • 35. 138 34 13 9 full empty 0 5 1 4 2 3 3 2
  • 36. 139 34 13 9 10 full empty 0 5 1 4 2 3 3 2 4 1
  • 37. 140 34 13 9 10 -3 full empty 0 5 1 4 2 3 3 2 4 1 5 0
  • 38. 141 • E.g. Readers and Writer Problem (Solution 1) – Multiple tasks are sharing a resource, and some of them want to read the resource and some want to write or modify the resource. – Allow multiple concurrent reader tasks simultaneous access, but serialize access for writer tasks (a writer may read). – A split binary semaphore is a collection of semaphores where at most one of the collection has the value 1, i.e., the sum of the semaphores is always less than or equal to one. – Split binary semaphores can be used to solve complicated mutual-exclusion problems by a technique called baton passing. – The rules of baton passing are: ∗ there is exactly one baton ∗ nobody moves in the entry/exit code unless they have it ∗ once the baton is released, cannot read/write variables in entry/exit
  • 39. 142 w r r r w w w Readers baton Writers r r w Arrivers r w
  • 40. 143 uSemaphore entry_q(1); // split binary semaphore uSemaphore read_q(0), write_q(0); int r_cnt = 0, w_cnt = 0; // auxiliary int r_del = 0, w_del = 0; void Reader::main() { entry_q.P(); // entry protocol if ( w_cnt > 0 ) { r_del += 1; entry_q.V(); read_q.P(); } r_cnt += 1; if ( r_del > 0 ) { r_del -= 1; read_q.V(); // pass baton } else { entry_q.V(); } yield(); // pretend to read entry_q.P(); // exit protocol r_cnt -= 1; if ( r_cnt == 0 && w_del > 0 ) { w_del -= 1; write_q.V(); // pass baton } else { entry_q.V(); } }
  • 41. 144 void Writer::main() { entry_q.P(); // entry protocol if ( r_cnt > 0 | | w_cnt > 0 ) { w_del += 1; entry_q.V(); write_q.P(); } w_cnt += 1; entry_q.V(); yield(); // pretend to write entry_q.P(); // exit protocol w_cnt -= 1; if ( r_del > 0 ) { r_del -= 1; read_q.V(); // pass baton } else if ( w_del > 0 ) { w_del -= 1; write_q.V(); // pass baton } else { entry_q.V(); } } – Problem: continuous stream of readers ⇒ no writer can get in, so starvation. • E.g. Readers and Writer Problem (Solution 2)
  • 42. 145 – Give writers priority and make the readers wait. – Change entry protocol for reader to the following: entry_q.P(); // entry protocol if ( w_cnt > 0 | | w_del > 0 ) { r_del += 1; entry_q.V(); read_q.P(); } r_cnt += 1; if ( r_del > 0 ) { r_del -= 1; read_q.V(); } else { entry_q.V(); } – Also, change writer’s exit protocol to favour writers: entry_q.P(); // exit protocol w_cnt -= 1; if ( w_del > 0 ) { // check writers first w_del -= 1; write_q.V(); } else if ( r_del > 0 ) { r_del -= 1; read_q.V(); } else { entry_q.V(); }
  • 43. 146 – Now readers can starve. • E.g. Readers and Writer Problem (Solution 3) w 12:30 r r w 2:00 1:00 baton 1:30 – Readers wait if there is a waiting writer, all readers are started after a writer (i.e. alternate group of readers then a writer) – There is a problem: staleness/freshness. • E.g. Readers and Writer Problem (Solution 4) – Service readers and writers in a first-in first-out (FIFO) fashion, but allow multiple concurrent readers. – Must put readers and writers on same condition variable to maintain temporal order but then lose what kind of task.
  • 44. 147 – Maintain a shadow list to know the kind of task is waiting at front of condition variable: semaphore t0 → t1 → t2 → t3 → t4 → . . . shadow-list w → r → w → r → r → . . .