Concurrency and - PowerPoint PPT Presentation

1 / 81
About This Presentation
Title:

Concurrency and

Description:

Prevents dangling references to local data ... Created thread has a pointer into its creator's memory danger of dangling reference ... – PowerPoint PPT presentation

Number of Views:40
Avg rating:3.0/5.0
Slides: 82
Provided by: benbr3
Learn more at: https://cs.nyu.edu
Category:

less

Transcript and Presenter's Notes

Title: Concurrency and


1
Concurrency and Real-Time Programming Supportin
Java, Ada, POSIX
From Tutorial for TOOLS-USA 2001 August 1,
2001 Santa Barbara, CA
Presented by Robert Dewar Programming
Languages Fall 2002, NYU
2
Topics
  • Concurrency issues
  • Basic model / lifetime
  • Mutual exclusion
  • Coordination / communication
  • Asynchrony
  • Interactions with exception handling
  • Real-time issues
  • Memory management / predictability
  • Scheduling and priorities (priority inversion
    avoidance)
  • Time / periodic activities
  • Java approach
  • Java language specification
  • Real-Time Specification for Java (Real-Time for
    Java Expert Group)
  • Core Extensions to Java (J-Consortium)
  • Ada 95 approach
  • Core language
  • Systems Programming and Real-Time Annexes
  • POSIX approach
  • Pthreads (1003.1c)

3
Concurrency Granularity / Terminology
  • Platform
  • Hardware OS language-specific run-time
    library
  • Process
  • Unit of concurrent execution on a platform
  • Communicates with other processes on the same
    platform or on different platforms
  • Communication / scheduling managed by the OS
    (same platform) or CORBA etc (different
    platforms)
  • Concurrency on a platform may be true parallelism
    (multi-processor) or multiplexed (uniprocessor)
  • Per-process resources include stack, memory,
    environment, file handles, ...
  • Switching/communication between processes is
    expensive
  • Thread (Task)
  • Unit of concurrent execution within a process
  • Communicates with other threads of same process
  • Shares per-process resources with other threads
    in the same process
  • Per-thread resources include PC, stack
  • Concurrency may be true parallelism or
    multiplexed
  • Communication / scheduling managed by the OS or
    by language-specific run-time library
  • Switching / communication between threads is
    cheap
  • Our focus threads in a uniprocessor environment

4
Summary of Issues
  • Concurrency
  • Basic model / generality
  • Lifetime properties
  • Creation, initialization, (self) termination,
    waiting for others to terminate
  • Mutual exclusion
  • Mechanism for locking a shared resource,
    including control over blocking/awakening a task
    that needs the resource in a particular state
  • Coordination (synchronization) / communication
  • Asynchrony
  • Event / interrupt handling
  • Asynchronous Transfer of Control
  • Suspension / resumption / termination (of / by
    others)
  • Interactions with exception handling
  • Libraries and thread safety
  • Real-Time
  • Predictability (time, space)
  • Scheduling policies / priority
  • Range of priority values
  • Avoidance of priority inversion
  • Clock and time-related issues and services

5
Overview of Java Concurrency Support (1)
  • Java Preliminaries
  • Smalltalk-based, dynamic, safety-sensitive OO
    language with built-in support for concurrency,
    exception handling
  • Dynamic data model
  • Aggregate data (arrays, class objects) on heap
  • Only primitive data and references on stack
  • Garbage Collection required
  • Two competing proposals for real-time extensions
  • Sun-sponsored Real-Time for Java Expert Group
  • J-Consortium
  • Basic concurrency model
  • Unit of concurrency is the thread
  • A thread is an instance of the class
    java.lang.Thread or one of its subclasses
  • run() method algorithm performed by each
    instance of the class
  • Programmer either extends Thread, or implements
    the Runnable interface
  • Override/implement run()
  • All threads are dynamically allocated
  • If implementing Runnable, construct a Thread
    object passing a Runnable as parameter

6
Overview of Java Concurrency Support (2)
  • Example of simple thread
  • Lifetime properties
  • Constructing a thread creates the resources that
    the thread needs (stack, etc.)
  • Activation is explicit, by invoking start()
  • Started thread runs concurrently with parent
  • Thread terminates when its run method returns
  • Parent does not need to wait for children to
    terminate
  • Restrictions on up-level references from inner
    classes prevent dangling references to parent
    stack data

public class Writer extends Thread final int
count public Writer(int count)this.countcount
public void run() for (int i1
iltcount i) System.out.println("Hello "
i) public static void main(
String args ) throws InterruptedException
Writer w new Writer(60) w.start() //
New thread of control invokes w.run()
w.join() // Wait for w to terminate
7
Overview of Java Concurrency Support (3)
  • Mutual exclusion
  • Shared data (volatile fields)
  • synchronized blocks/methods
  • Thread coordination/communication
  • Pass data to new thread via constructor
  • Pulsed event - wait() / notify()
  • Broadcast event - wait() / notifyAll()
  • join() suspends caller until the target thread
    completes
  • Asynchrony
  • interrupt() sets a bit that can be polled
  • Asynchronous termination
  • stop() is deprecated
  • destroy() is discouraged
  • suspend() / resume() have been deprecated
  • RTJEG, J-C proposals include event / interrupt
    handling, ATC, asynchronous termination
  • Interaction with exception handling
  • No asynchronous exceptions
  • Various thread-related exceptions
  • Thread propagating an unhandled exception

8
Overview of Ada Concurrency Support (1)
  • Ada 95 preliminaries
  • Pascal-based ISO Standard OO language with
    built-in support for packages (modules),
    concurrency, exception handling, generic
    templates, ...
  • Traditional data model (static storage,
    stack(s), heap)
  • Aggregate data (arrays, records) go on the stack
    unless dynamically allocated
  • Implementation not required to supply Garbage
    Collection
  • Specialized Needs Annexes support systems
    programming, real-time, several other domains
  • Basic concurrency model
  • Unit of concurrency (thread) is the task
  • Task specification interface to other tasks
  • Often simply just the task name
  • Task body implementation (algorithm)
  • Comprises declarations, statements
  • Task type serves as a template for task objects
    performing the same algorithm
  • Tasks and task types are declarations and may
    appear in global packages or local scopes
  • Tasks follow normal block structure rules
  • Each task has own stack
  • Task body may refer (with care -) to data in
    outer scopes, may declare inner tasks
  • Task objects may be declared or dynamically
    allocated

9
Overview of Ada Concurrency Support (2)
  • Example of declared task object
  • Lifetime properties
  • Declared task starts (is activated) implicitly at
    the begin of parent unit
  • Allocated task starts at the point of allocation
  • Task statements execute concurrently with
    statements of parent
  • Task completes when it reaches its end
  • Master is suspended when it reaches its end,
    until each child task terminates
  • Prevents dangling references to local data
  • No explicit mechanism (such as Javas join()) to
    wait for another task to terminate

with Ada.Text_IOprocedure Example1 is Count
Integer 60 task Writer -- Specification
task body Writer is -- Body begin for I in
1..Count loop Ada.Text_IO.Put_Line( "Hello"
Integer'Image(I)) delay 1.0 -- Suspend
for at least 1.0 second end loop end
Writerbegin -- Writer activated null --
Main procedure suspended until Writer
terminatesend Example1
10
Overview of Ada Concurrency Support (3)
  • Example of task type / dynamic allocation
  • Mutual exclusion
  • Shared data, pragma Volatile / Atomic
  • Protected objects / types
  • Data protected operations that are executed
    with mutual exclusion
  • Passive task that sequentializes access to a
    data structure via explicit communication
    (rendezvous)
  • Explicit mutex-like mechanism (definable as
    protected object/type) that is locked and
    unlocked

with Ada.Text_IOprocedure Example2 is task
type Writer(Count Natural) -- Specification
type Writer_Ref is access Writer Ref
Writer_Ref task body Writer is -- Body
begin for I in 1..Count loop
Ada.Text_IO.Put_Line( "Hello" I'Img)
delay 1.0 -- Suspend for at least 1.0 second
end loop end Writerbegin Ref new
Writer(60) -- activates new Writer task object
-- Main procedure suspended until Writer object
terminatesend Example2
11
Overview of Ada Concurrency Support (4)
  • Coordination / communication
  • Pass data to task via discriminant or rendezvous
  • Suspension_Object
  • Binary semaphore with 1-element queue
  • Rendezvous
  • Explicit inter-task communication
  • Implicit wait for dependent tasks
  • Asynchrony
  • Event handling via dedicated task, interrupt
    handler
  • Asynch interactions subject to abort deferral
  • abort statement
  • Asynchronous transfer of control via timeout or
    rendezvous request
  • Hold / Continue procedures (suspend / resume)
  • Interaction with exception handling
  • No asynchronous exceptions
  • Tasking_Error raised at language-defined points
  • Task propagating an (unhandled) exception
    terminates silently
  • Other functionality
  • Per-task attributes

12
Overview of POSIX Concurrency Support (1)
  • Basic concurrency model
  • A thread is identified by an instance of (opaque)
    type pthread_t
  • Threads may be allocated dynamically or declared
    locally (on the stack) or statically
  • Program creates / starts a thread by calling
    pthread_create, passing an attributes
    structure, the function that the thread will be
    executing, and the functions arguments
  • Thread function takes and returns void
  • Return value passed to joining thread
  • Example
  • Notation POSIX call in upper-case is a macro
    whose expansion includes querying the error
    return code

include ltpthread.hgt include ltstdio.hgt void
tfunc(void arg) // thread function int
count ( (int)arg ) int j for (j1 j lt
count j) printf("Hello d\n", j)
return NULL int main(int argc, char argv)
// main thread pthread_t pthread int
pthread_arg 60 PTHREAD_CREATE( pthread,
NULL, tfunc,
(void)pthread_arg) PTHREAD_JOIN( pthread,
NULL )
13
Overview of POSIX Concurrency Support (2)
  • Lifetime properties
  • Thread starts executing its thread function as
    result of pthread_create, concurrent with creator
  • Termination
  • A thread terminates via a return statement or by
    invoking pthread_exit
  • Both deliver a result to a joining thread, but
    pthread_exit also invokes cleanup handlers
  • A terminated thread may continue to hold system
    resources until it is recycled
  • Detachment and recycling
  • A thread is detachable if
  • It has been the target of a pthread_join or a
    pthread_detach (either before or after it has
    terminated), or
  • it was created with its detachstate attribute set
  • A terminated detachable thread is recycled,
    releasing all system resources not released at
    termination
  • No hierarchical relationship among threads
  • Created thread has a pointer into its creators
    memory ? danger of dangling reference
  • Main thread is special in that when it returns it
    terminates the process, killing all other threads
  • To avoid this mass transitive threadicide, main
    thread can pthread_exit rather than return

14
Overview of POSIX Concurrency Support (3)
  • Mutual exclusion
  • Shared (volatile) data
  • Mutexes (pthread_mutex_t type) with lock/unlock
    functions
  • Coordination / communication
  • Condition variables (pthread_cond_t type) with
    pulsed and broadcast events
  • Semaphores
  • Data passed to thread function at pthread_create,
    result delivered to joining thread at return or
    pthread_exit
  • Asynchrony
  • Thread cancellation with control over immediacy
    and ability to do cleanup
  • Interaction with exception handling
  • Complicated relationship with signals
  • Consistent error-return conventions
  • The result of each pthread function is an int
    error code (0 ? normal)
  • If the function needs to return a result, it does
    so in an address () parameter
  • No use of errno
  • Other
  • Thread-specific data area
  • pthread once functions

15
Comparison Basic Model / Lifetime
  • Points of difference
  • Nature of unit of concurrency class, task,
    function
  • Implicit versus explicit activation
  • How parameters are passed / how result
    communicated
  • Methodology / reliability
  • Ada and Java provide type checking, prevent
    dangling references
  • Flexibility / generality
  • All three provide roughly the same expressive
    power
  • POSIX allows a new thread to be given its
    parameters explicitly on thread creation
  • POSIX allows a thread to return a value to a
    joining thread
  • Efficiency
  • Ada requires run-time support to manage task
    dependence hierarchy

16
Mutual Exclusion in Ada via Shared Data
  • Example
  • One task repeatedly updates an integer value
  • Another task repeatedly displays it
  • Advantage
  • Efficiency
  • Need pragma Atomic to ensure that

with Ada.Text_IO procedure Example3 is Global
Integer 0 pragma Atomic( Global )
task Updater task Reporter task body
Updater is begin loop Global
Global1 delay 1.0 -- 1 second
end loop end Updater task body Reporter
is begin loop
Ada.Text_IO.Put_Line( Global'Img )
delay 2.0 -- 2 seconds end loop end
Reporter begin null end Example3
Note the assignment statement is not atomic
17
Mutual Exclusion in Java via Shared Data
  • Java version of previous example
  • Comments
  • Same advantages and disadvantages as Ada version

public class Example4 static volatile int
global 0 public static void main(String
args) Updater u new Updater()
Reporter r new Reporter() u.start()
r.start() class Updater extends
Thread public void run() while(true)
Example1.global ... sleep( 1000 ) ...
// try block omitted class Reporter
extends Thread public void run()
while(true) System.out.println(Example1.gl
obal) ... sleep( 2000 ) ... //
try block omitted
18
Mutual Exclusion in Ada via Protected Object
with Ada.Integer_Text_IO procedure Example5 is
type Position is record X, Y Integer
0 end record protected Global is
procedure Update function Value return
Position private Data Position
end Global protected body Global is
procedure Update is begin Data.X
Data.X1 Data.Y Data.Y1 end
Update function Value return Position is
begin return Data end Value
end Global task Updater task Reporter
task body Updater is begin loop
Global.Update delay 1.0 -- 1 second
end loop end Updater task body
Reporter is P Position begin
loop P Global.Value
Ada.Integer_Text_IO.Put (P.X)
Ada.Integer_Text_IO.Put (P.Y) delay
2.0 -- 2 seconds end loop end
Reporter begin null end Example5
Interface
Implementation
Executed with mutual exclusion
19
Basic Properties of Ada Protected Objects
  • A protected object is a data object that is
    shared across multiple tasks but with mutually
    exclusive access via a (conceptual) lock
  • The rules support CREW access (Concurrent Read,
    Exclusive Write)
  • Form of a protected object declaration
  • Encapsulation is enforced
  • Client code can only access the protected
    components through protected operations
  • Protected operations illustrated in Example2
  • Procedure may read or write the components
  • Function may read the components, not write
    them
  • The protected body provides the implementation of
    the protected operations
  • Comments on Example2
  • Use of protected object ensures that only one of
    the two tasks at a time can be executing a
    protected operation
  • Scales up if we add more accessing tasks
  • Allows concurrent execution of reporter tasks

Data may only be in the private part
protected Object_Name is protected_operation_
specification private
protected_component_declaration end
Object_Name
20
Mutual Exclusion in Java viaSynchronized Blocks
class Position int x0, y0
public class Example6 public static void
main(String args) Position global new
Position() Updater u new Updater(
global ) Reporter r new Reporter( global
) u.start() r.start()
class Updater extends Thread private final
Position pu Updater( Position p ) pup
public void run() while(true)
synchronized(pu) pu.x
pu.y ... sleep( 1000 ) ...

class Reporter extends Thread private final
Position pr Reporter( Position p ) prp
public void run() while(true)
synchronized(pr) System.out.println(pr.x)
System.out.println(pr.y)
... sleep( 2000 ) ...
21
Semantics of Synchronized Blocks
  • Each object has a lock
  • Suppose thread t executes synchronized(p)...
  • In order to enter the ... block, t must acquire
    the lock associated with the object referenced by
    p
  • If the object is currently unlocked, t acquires
    the lock and sets the lock count to 1, and then
    proceeds to execute the block
  • If t currently holds the lock on the object, t
    increments its lock count for the object by 1,
    and proceeds to execute the block
  • If another thread holds the lock on the object, t
    is stalled
  • Leaving a synchronized block (either normally or
    abruptly)
  • t decrements its lock count on the object by 1
  • If the lock count is still positive, t proceeds
    in its execution
  • If the lock count is zero, the threads locked
    out of the object become eligible to run, and t
    stays eligible to run
  • But this is not an official scheduling point
  • If each thread brackets its accesses inside a
    synchronized block on the object, mutually
    exclusive accesses to the object are ensured
  • No need to specify volatile

22
Mutual Exclusion in Java viaSynchronized Methods
class Position private int x0, y0 public
synchronized void incr() x 1 y
1 public synchronized int value()
return new int2x, y
public class Example7 public static void
main(String args) Position global new
Position() Updater u new Updater(
global ) Reporter r new Reporter( global
) u.start() r.start()
class Updater extends Thread private final
Position pu Updater( Position p ) pup
public void run() while(true)
pu.incr() ... sleep( 1000 ) ...

class Reporter extends Thread private final
Position pr Reporter( Position p ) prp
public void run() while(true)
int arr pr.value() System.out.println(a
rr0) System.out.println(arr1)
... sleep( 2000 ) ...
23
Comments on Synchronized Blocks / Methods
  • Effect of synchronized instance method is as
    though body of method was in a synchronized(this)
    block
  • Generally better to use synchronized methods
    versus synchronized blocks
  • Centralizes mutual exclusion logic
  • For efficiency, have a non-synchronized method
    with synchronized(this) sections of code
  • Synchronized accesses to static fields
  • A synchronized block may synchronize on a class
    object
  • The class literal Foo.class returns a reference
    to the class object for class Foo
  • Typical style in a constructor that needs to
    access static fields
  • A static method may be declared as synchronized
  • Constructors are not specified as synchronized
  • Only one thread can be operating on a given
    object through a constructor
  • Invoking obj.wait() releases lock on obj
  • All other blocking methods (join(), sleep(),
    blocking I/O) do not release the lock

class MyClass private static int count0
MyClass() synchronized(MyClass.class)
count ...
24
Mutual Exclusion in POSIX via Mutex
  • A mutex is an instance of type pthread_mutex_t
  • Initialization determines whether a pthread can
    successfully lock a mutex it has already locked
  • PTHREAD_MUTEX_INITIALIZER (fast mutex)
  • Attempt to relock will fail
  • PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
    (recursive mutex)
  • Attempt to relock will succeed
  • Operations on a mutex
  • pthread_mutex_lock(mutex)
  • Blocks caller if mutex locked
  • Deadlock condition indicated via error code
  • pthread_mutex_trylock(mutex)
  • Does not block caller
  • pthread_mutex_unlock(mutex)
  • Release waiting pthread
  • pthread_mutex_destroy(mutex)
  • Release mutex resources
  • Can reuse mutex if reinitialize

25
Monitors
  • In most cases where mutual exclusion is required
    there is also a synchronization constraint
  • A task performing an operation on the object
    needs to wait until the object is in a state for
    which the operation makes sense
  • Example bounded buffer with Put and Get
  • Consumer calling Get must block if buffer is
    empty
  • Producer calling Put must block if buffer is full
  • The monitor is a classical concurrency mechanism
    that captures mutual exclusion state
    synchronization
  • Encapsulation
  • State data is hidden, only accessible through
    operations exported from the monitor
  • Implementation must guarantee that at most one
    task is executing an operation on the monitor
  • Synchronization is via condition variables local
    to the monitor
  • Monitor operations invoke wait/signal on the
    condition variables
  • A task calling wait is unconditionally blocked
    (in a queue associated with that condition
    variable), releasing the monitor
  • A task calling signal awakens one task waiting
    for that variable and otherwise has no effect
  • Proposed/researched by Dijkstra, Brinch-Hansen,
    Hoare in late 1960s and early 1970s

Synchronization in the correct (versus Java)
sense
26
Monitor Example Bounded Buffer
monitor Buffer
export Put, Get, Size const
Max_Size 10 var Data
array1..Max_Size of Whatever Next_In,
Next_Out 1..Max_Size Count
0..Max_Size NonEmpty, NonFull condition
procedure Put(Item Whatever) begin if
CountMax_Size then Wait( NonFull )
DataNext_In Item Next_In Next_In mod
Max_Size 1 Count Count 1
Signal( NonEmpty ) end Put procedure
Get(Item var Whatever) begin if Count0
then Wait( NonEmpty ) Item
DataNext_Out Next_Out Next_Out mod
Max_Size 1 Count Count - 1
Signal( NonFull ) end Get function Size
Integer begin Size Count end
Size begin Count 0 Next_In 1
Next_Out 1 end Buffer
27
Monitor Critique
  • Semantic issues
  • If several tasks waiting for a condition
    variable, which one is unblocked by a signal?
  • Longest-waiting, highest priority, unspecified,
    ...
  • Which task (signaler or unblocked waiter) holds
    the monitor after a signal
  • Signaler?
  • Unblocked waiter?
  • Then when does signaler regain the monitor
  • Avoid problem by requiring signal either to
    implicitly return or to be the last statement?
  • Depending on semantics, may need while vs if in
    the code that checks the wait condition
  • Advantages
  • Encapsulation
  • Efficient implementation
  • Avoids some race conditions
  • Disadvantages
  • Sacrifices potential concurrency
  • Operations that dont affect the monitors state
    (e.g. Size) still require mutual exclusion
  • Condition variables are low-level / error-prone
  • Programmer must ensure that monitor is in a
    consistent state when wait/signal are called
  • Nesting monitor calls can deadlock, even without
    using condition variables

28
Monitors and Java
  • Every object is a monitor in some sense
  • Each object obj has a mutual exclusion lock, and
    certain code is executed under control of that
    lock
  • Blocks that are synchronized on obj
  • Instance methods on objs class that are declared
    as synchronized
  • Static synchronized methods for obj if obj is a
    class
  • But encapsulation depends on programmer style
  • Non-synchronized methods, and accesses to
    non-private data from client code, are not
    subject to mutual exclusion
  • No special facility for condition variables
  • Any object (generally the one being accessed by
    synchronized code) can be used as a condition
    variable via wait() / notify()
  • But that means that there is only one condition
    directly associated with the object
  • To invoke wait() or notify() on an object, the
    calling thread needs to hold the lock on the
    object
  • Otherwise throws a run-time exception
  • The notifying thread does not release the lock
  • Waiting threads thus generally need to do their
    wait in a while statement versus a simple if
  • No guarantee which waiting thread is awakened by
    a notify

29
Bounded Buffer in Java
  • Notes
  • Essential for each wait() condition to be in a
    while loop and not simply an if statement

public class BoundedBuffer public static final
int maxSize10 private final Object data
new ObjectmaxSize private int nextIn0,
nextOut0 private volatile int count0
public synchronized void put(Object item)
throws InterruptedException while (count
max) this.wait() datanextIn item
nextIn (nextIn 1) max count
this.notify() //a waiting consumer, if any
public synchronized Object get() throws
InterruptedException while (count 0)
this.wait() Object result
datanextOut datanextOut null
nextOut (nextOut 1) max
count-- this.notify() // a waiting
producer, if any return result public
int size() // not synchronized return
count
30
Monitors and Ada Protected Objects
  • Encapsulation enforced in both
  • Data components are inaccessible to clients
  • Mutual exclusion enforced in both
  • All accesses are via protected operations, which
    are executed with mutual exclusion (CREW)
  • Condition variables
  • A protected entry is a protected operation
    guarded by a boolean condition (barrier) which,
    if false, blocks the calling task
  • Barrier condition can safely reference the
    components of the protected object and also the
    Count attribute
  • E'Count number of tasks queued on entry E
  • Value does not change while a protected operation
    is in progress (avoids race condition)
  • Barrier expressions are Ada analog of condition
    variables, but higher level (wait and signal
    implicit)
  • Caller waits if the barrier is False (and
    releases the lock on the object)
  • Barrier conditions for non-empty queues are
    evaluated at the end of protected procedures and
    protected entries
  • If any are True, queuing policy establishes which
    task is made ready
  • Protected operations (unlike monitor operations)
    are non-blocking
  • Allows efficient implementation of lock

31
Bounded Buffer in Ada
package Bounded_Buffer_Pkg is Max_Length
constant 10 type W_Array is array(1
.. Max_Length) of Whatever protected
Bounded_Buffer is entry Put( Item in
Whatever ) entry Get( Item out Whatever
) function Size private Next_In,
Next_Out Positive 1 Count Natural
0 Data W_Array end Bounded_Buffer end
Bounded_Buffer_Pkg
package body Bounded_Buffer_Pkg is protected
body Bounded_Buffer is entry Put( Item in
Whatever ) when Count lt Max_Length is begin
Data(Next_In) Item Next_In
Next_In mod Max_Length 1 Count
Count1 end Put entry Get(
Item out Whatever ) when Count gt 0 is
begin Item Data(Next_Out)
Next_Out Next_Out mod Max_Length 1
Count Count-1 end Get function
Size is begin return Count end
Size end Bounded_Buffer end
Bounded_Buffer_Pkg
Evaluate barriers
32
Monitors and POSIXMutex Condition Variables
  • POSIX supplies type pthread_cond_t for condition
    variables
  • Always used in conjunction with a mutex
  • Avoids race conditions such as a thread calling
    wait and missing a signal that is issued before
    the thread is enqueued
  • May be used to simulate a monitor, or simply as
    an inter-thread coordination mechanism
  • Initialized via PTHREAD_COND_INITIALIZER or via
    pthread_cond_init function
  • Operations
  • Signaling operations
  • pthread_cond_signal( cond_vbl )
  • Pulsed event
  • No guarantee which waiter is awakened
  • pthread_cond_broadcast (cond_vbl )
  • Broadcast event
  • Waiting operations
  • pthread_cond_wait( cond_vbl, mutex )
  • pthread_cond_timedwait(cond_vbl, mutex,
    timeout)
  • Initialization
  • pthread_cond_init( cond_val )
  • Resource release
  • pthread_cond_destroy( cond_vbl )

33
Bounded Buffer in POSIX ()
include ltpthread.hgt define MAX_LENGTH
10 define WHATEVER float typedef struct
pthread_mutex_t mutex pthread_cond_t
non_full pthread_cond_t non_empty int
next_in, next_out, count WHATEVER
dataMAX_LENGTH bounded_buffer_t void put(
WHATEVER item, bounded_buffer_t b )
PTHREAD_MUTEX_LOCK((b-gtmutex)) while
(b-gtcount MAX_LENGTH) PTHREAD_COND_WAIT((
b-gtnon_full), (b-gtmutex)) ... / Put data
in buffer, update count and next_in /
PTHREAD_COND_SIGNAL((b-gtnon_empty))
PTHREAD_MUTEX_UNLOCK((b-gtmutex)) void get(
WHATEVER item, bounded_buffer_t b )
PTHREAD_MUTEX_LOCK((b-gtmutex)) while
(b-gtcount 0) PTHREAD_COND_WAIT((b-gtnon_em
pty), (b-gtmutex)) ... / Get data from
buffer, update count and next_out /
PTHREAD_COND_SIGNAL((b-gtnon_full))
PTHREAD_MUTEX_UNLOCK((b-gtmutex)) int size(
bounded_buffer_t b ) int n
PTHREAD_MUTEX_LOCK((b-gtmutex)) n b-gtcount
PTHREAD_MUTEX_UNLOCK((b-gtmutex)) return
n / Initializer function also required
() Based on example in Burns Wellings,
Real-Time Systems and Programming Languages, pp.
253-254
34
Comparison of Mutual Exclusion Approaches
  • Points of difference
  • Expression of mutual exclusion in program
  • Explicit code markers in POSIX (lock/unlock
    mutex)
  • Either explicit code marker (synchronized block)
    or encapsulated (synchronized method) in Java
  • Encapsulated (protected object) in Ada
  • No explicit condition variables in Java
  • Blocking prohibited in protected operations (Ada)
  • Locks are implicitly recursive in Java and Ada,
    programmer decides whethr fast or recursive in
    POSIX
  • Methodology / reliability
  • All provide necessary mutual exclusion
  • Ada entry barrier is higher level than condition
    variable
  • Absence of condition variable from Java can lead
    to clumsy or obscure style
  • Main reliability issue is interaction between
    mutual exclusion and asynchrony, described below
  • Flexibility / generality
  • Ada restricts protected operations to be
    non-blocking
  • Efficiency
  • Ada provides potential for concurrent reads
  • Ada does not require queue management

35
Coordination / Communication Mechanisms
  • Pulsed Event
  • Waiter blocks unconditionally
  • Signaler awakens exactly one waiter (if one or
    more), otherwise event is discarded
  • Broadcast Event
  • Waiter blocks unconditionally
  • Signaler awakens all waiters (if one or more),
    otherwise event is discarded
  • Persistent Event (Binary Semaphore)
  • Signaler allows one and only one task to proceed
    past a wait
  • Some task that already has, or the next task that
    subsequently will, call wait
  • Counting semaphore
  • A generalization of binary semaphore, where the
    number of occurrences of signal are remembered
  • Simple 2-task synchronization
  • Persistent event with a one-element queue
  • Direct inter-task synchronous communication
  • Rendezvous, where the task that initiates the
    communication waits until its partner is ready

36
Pulsed Event
  • Java
  • Any object can serve as a pulsed event via wait()
    / notify()
  • Calls on these methods must be in code
    synchronized on the object
  • wait() releases the lock, notify() doesnt
  • wait() can throw InterruptedException
  • An overloaded version of wait() can time out, but
    no direct way to know whether the return was
    normal or via timeout
  • Ada
  • Protected object can model a pulsed event
  • Can time out on any entry via select statement
  • Cant awaken a blocked task other than via abort
  • POSIX
  • Condition variable can serve as pulsed event

protected Pulsed_Signal is entry Wait
procedure Signal private Signaled Boolean
False end Pulsed_Signal
protected body Pulsed_Signal is entry Wait when
Signaled is begin Signaled False end
Wait procedure Signal is begin Signaled
Wait'Countgt0 end Signal end Pulsed_Signal
37
Broadcast Event
  • Java
  • Any object can serve as a broadcast event via
    wait() / notifyAll()
  • Calls on these methods must be in code
    synchronized on the object
  • Ada
  • Protected object can model a broadcast event
  • Protected object can model more general forms,
    such as sending data with the signal, to be
    retrieved by each awakened task
  • Locking protocol / barrier evaluation rules
    prevent race conditions
  • POSIX
  • Condition variable can serve as broadcast signal

protected Broadcast_Signal is entry Wait
procedure Signal private Signaled Boolean
False end Pulsed_Signal
protected body Broadcast_Signal is entry Wait
when Signaled is begin Signaled
Wait'Countgt0 end Wait procedure Signal is
begin Signaled Wait'Countgt0 end
Signal end Pulsed_Signal
38
Semaphores (Persistent Event)
  • Binary semaphore expressible in Java
  • J-Consortium spec includes binary and counting
    semaphores
  • Binary semaphore expressible in Ada

public class BinarySemaphore private boolean
signaled false public synchronized void
await() throws InterruptedException while
(!signaled) this.wait() signaledfalse
public synchronized void signal()
signaledtrue this.notify()
protected type Binary_Semaphore is entry Wait
procedure Signal private Signaled Boolean
False end Binary_Semaphore
protected body Binary_Semaphore is entry Wait
when Signaled is begin Signaled False
end Wait procedure Signal is begin
Signaled True end Signal end
Binary_Semaphore
39
Simple Two-Task Synchronization
  • Java, POSIX
  • No built-in support
  • Ada
  • Type Suspension_Object in package
    Ada.Synchronous_Task_Control
  • Procedure Suspend_Until_True(SO) blocks caller
    until SO becomes true, and then resets SO to
    false
  • Procedure Set_True(SO) sets SOs state to true
  • Bounded error if a task calls
    Suspend_Until_True(SO) while another task is
    waiting for the same SO

procedure Proc is task Setter task
Retriever SO Suspension_Object Data
array (1..1000) of Float task body Setter is
begin ... -- Initialize Data
Set_True(SO) ... end Setter task body
Retriever is begin Suspend_Until_True(SO)
... -- Use data end Setter begin
null end Proc
40
Direct Synchronous Inter-Task Communication (1)
  • Calling task (caller)
  • Requests action from another task (the callee),
    and blocks until callee is ready to perform the
    action
  • Called task (callee)
  • Indicates readiness to accept a request from a
    caller, and blocks until a request arrives
  • Rendezvous
  • Performance of the requested action by callee, on
    behalf of a caller
  • Parameters may be passed in either or both
    directions
  • Both caller and callee are unblocked after
    rendezvous completes
  • Java
  • No direct support
  • Can model via wait / notify, but complicated
  • POSIX
  • Same comments as for Java

T1
T2
  • T2, do action A ?
  • Wait for T2 to start action A
  • (T2 does action A)
  • Wait for T2 to complete action A
  • Accept request for action A from T1 ?
  • Wait for request for action A from T1
  • Do action A
  • Awaken caller

41
Direct Synchronous Inter-Task Communication (2)
  • Ada
  • Action is referred to as a tasks entry
  • Declared in the tasks specification
  • Caller makes entry call, similar syntactically to
    a procedure call
  • Callee accepts entry call via an accept statement
  • Caller identifies callee but not vice versa
  • Many callers may call the same entry, requiring a
    queue
  • Often callee is a server that sequentializes
    access to a shared resource
  • Sometimes protected object is not sufficient,
    e.g. if action may block
  • In most cases the server can perform any of
    several actions, and the syntax needs to reflect
    this flexibility
  • Also in most cases the server is written as an
    infinite loop (not known in advance how many
    requests will be made) so termination is an issue
  • Ada provides special syntax for a server to
    automatically terminate when no further
    communication with it is possible
  • Caller and/or callee may time out
  • Timeout canceled at start of rendezvous

42
Direct Synchronous Inter-Task Communication (3)
  • Ada example

task Sequentialized_Output is entry Put_Line(
Item String ) entry Put( Item String
) end Sequentialized_Output
task body Sequentialized_Output is begin loop
select accept Put_Line( Item String )
do Ada.Text_IO.Put_Line( Item )
end Put_Line or accept Put( Item
String ) do Ada.Text_IO.Put( Item )
end Put or terminate end
select end loop end Sequentialized_Output
task Outputter1 task body Outputter1 is begin
... Sequentialized_OutPut. Put("Hello")
... end Outputter1
task Outputter2 task body Outputter2 is begin
... Sequentialized_Output.
Put("Bonjour") ... end Outputter2
43
Comparison of Coordination/Communication
Mechanisms
  • Points of difference
  • Different choice of building blocks
  • Ada Suspension_Object, protected object,
    rendezvous
  • Java, POSIX pulsed/broadcast events
  • Java allows interruption of blocked thread
  • Methodology / reliability
  • Adas high-level feature(rendezvous) supports
    good practice
  • Potential for undetected bug in Ada if a task
    calls Suspend_Until_True on a Suspension_Object
    that already has a waiting task
  • Flexibility / generality
  • Major difference among the languages is that Ada
    is the only one to provide rendezvous as built-in
    communication mechanism
  • Efficiency
  • No major differences in implementation efficiency
    for mechanisms common to the three approaches
  • Adas Suspension_Object has potential for greater
    efficiency than semaphores

44
Asynchrony Mechanisms
  • Setting/Polling
  • Setting a datum in a task/thread that is polled
    by the affected task/thread
  • Asynchronous Event Handling
  • Responding to asynchronous events generated
    internally (by application threads) or externally
    (by interrupts)
  • Resumptive interrupted thread continues at the
    point of interruption, after the handler
    completes
  • Combine with polling or ATC to affect the
    interrupted thread
  • Asynchronous Termination
  • Aborting a task/thread
  • Immediacy are there regions in which a task /
    thread defers requests for it to be aborted?
  • ATC
  • Causing a task to branch based on an asynchronous
    occurrence
  • Immediacy are there regions in which a task /
    thread defers requests for it to have an ATC?
  • Suspend/resume
  • Causing a thread to suspend its execution, and
    later causing the thread to be resumed
  • Immediacy are there regions in which a task /
    thread defers requests for it to be suspended?

45
Setting / Polling
  • Not exactly asynchronous (since the affected
    task/thread checks synchronously)
  • But often useful and arguably better than
    asynchronous techniques
  • Ada
  • No built-in mechanism, but can simulate via
    protected object or pragma Atomic variable global
    to setter and poller
  • Java
  • t.interrupt() sets interruption status flag in
    the target thread t
  • Static Thread method boolean interrupted()
    returns current threads interruption status flag
    and resets it
  • Boolean method t.isInterrupted() returns target
    threads interruption status flag
  • If t.interrupt() is invoked on a blocked thread
    t, t is awakened and an InterruptedException (a
    checked exception) is thrown
  • Each of the methods thr.join(), Thread.sleep(),
    and obj.wait() has a throws InterruptedException
    clause
  • POSIX
  • No built-in mechanism, but can simulate via
    volatile variable global to setter and poller

46
Asynchronous Event Handling
  • Ada
  • No specific mechanism for asynch event handling
  • Interrupt handlers can be modeled by specially
    identified protected procedures, executed (at
    least conceptually) by the hardware
  • Other asynch event handlers modeled by tasks
  • Java (RTSJ)
  • Classes AsyncEvent (AE), AsyncEventHandler
    (AEH) model asynchronous events, and handlers
    for such events, respectively
  • Programmer overrides one of the AEH methods to
    define the handlers action
  • Program can register one or more AEHs with any AE
    (listener model)
  • An AEH is a schedulable entity, like a thread
    (but not necessarily a dedicated thread)
  • When an AE is fired, all registered handlers are
    scheduled based on their scheduling parameters
  • Program needs to manage any data queuing
  • Methods allow dealing with event bursts
  • Scales up to large number of events, handlers
  • POSIX
  • Messy interaction between signals (originally a
    process-based mechanism) and threads

47
Asynchronous Termination (1)
  • Ada
  • Abort statement sets the aborted tasks state to
    abnormal, but this does not necessarily terminate
    the aborted task immediately
  • For safety, certain contexts are abort-deferred
    e.g.
  • Accept statements
  • Protected operations
  • Real-Time Annex requires implementation to
    terminate an abnormal task as soon as it is
    outside an abort-deferred region
  • Java Language Spec
  • No notion of abort-deferred region
  • Invoke t.stop(Throwable exc) or t.stop()
  • Halt t asynchronously, and throw exc or
    ThreadDeath object in t
  • Then effect is as though propagating an unchecked
    exception
  • Deprecated (data may be left in an inconsistent
    state if t stopped while in synchronized code)
  • Invoke t.destroy()
  • Halt t, with no cleanup and no release of locks
  • Not (yet -) deprecated but can lead to deadlock
  • Invoke System.exit(int status)
  • Terminates the JVM
  • By convention, nonzero status ? abnormal
    termination

48
Asynchronous Termination (2)
  • Java Language Spec (contd.)
  • Recommended style is to use interrupt()
  • Main issue is latency
  • RTSJ
  • Synchronized code, and methods that do not
    explicitly have a throws clause for AIE, are
    abort deferred
  • To abort a thread, invoke t.interrupt() and have
    t do its processing in an asynchronously
    interruptible method

class Boss extends Thread Thread slave
Boss(Thread slave) this.slaveslave public
void run() ... if (...)
slave.interrupt() // abort slave ...
class PollingSlave extends Thread
public void run() while (!Thread.interrupted
()) ... // main processing
... // pre-shutdown actions
49
Asynchronous Termination (3)
  • J-Consortium
  • abort() method aborts a thread
  • Synchronized code is not necessarily
    abort-deferred
  • May need to terminate a deadlocked thread that is
    in synchronized code
  • Synchronized code in objects that implement the
    Atomic interface is abort deferred
  • POSIX
  • A pthread can set its cancellation state (enabled
    or disabled) and, if enabled, its cancellation
    type (asynchronous or deferred)
  • pthread_set_cancelstate(newstate, oldstate)
  • PTHREAD_CANCEL_DISABLE
  • PTHREAD_CANCEL_ENABLE
  • pthread_set_canceltype(newtype, oldtype)
  • PTHREAD_CANCEL_ASYNCHRONOUS
  • PTHREAD_CANCEL_DEFERRED
  • Default setting enabled, deferred cancellation
  • Deferred ? cancel at next cancellation point
  • Minimal set of cancellation points defined by
    standard, others can be added by implementation
  • pthread_cancel( pthr ) sends cancellation
    request
  • Cleanup handlers give the cancelled thread the
    opportunity to consistentize data, unlock mutexes

50
Asynchronous Transfer of Control (ATC)
  • What is it
  • A mechanism whereby a triggering thread (possibly
    an async event handler) can cause a target
    thread to branch unconditionally, without any
    explicit action from the target thread
  • Controversial facility
  • Triggering thread does not know what state the
    target thread is in when the ATC is initiated
  • Target thread must be coded carefully in presence
    of ATC
  • Implementation cost / complexity
  • Interaction with synchronized code
  • Why included in spec
  • User community requirement
  • Useful for certain idioms
  • Time out of long computation when partial result
    is acceptable
  • Abort an iteration of a loop
  • Terminate a thread
  • ATC may have shorter latency than polling

51
Asynchronous Transfer of Control (1)
  • Ada
  • Allow controlled ATC, where the effect is
    restricted to an explicit syntactic context
  • Restrict the ATC triggering conditions
  • Time out
  • Acceptance of an entry call
  • Defer effect of ATC until affected task is
    outside abort-deferred region
  • Java (RTSJ)
  • ATC based on model of asynchronous exceptions,
    thrown only at threads that have explicitly
    enabled them
  • ATC deferred in synchronized code and in methods
    that lack a throws AIE clause
  • Timeout is a specific kind of AIE

function Eval(Interval Duration) return Float
is X Float 0.0 begin select delay
Interval return X then abort while
... loop ... X ... ... end loop
end select return X end Eval
1
3a
2
3b
52
Asynchronous Transfer of Control (2)
abstract class Func abstract double f(double
x) throws AIE volatile double current //
assumes atomic class MyFunc extends Func
double f(double x) throws AIE current
... while(...) ... current ...
return current class SuccessiveApproximati
on static boolean finished static double
calc(Func func, double arg, long ms) double
result 0.0 new Timed( new RelativeTime(ms,
0) ).doInterruptible( new
Interruptible() public void run(AIE e)
throws AIE result func.f(arg)
finished true
public void interruptAction(AIE e)
result func.current finished
false ) return result
public static void main(String args)
MyFunc mf new MyFunc() double answer
calc(mf, 100.0, 1000) // run mf.f(100.0) for
at most 1 second System.out.println(answer)
System.out.println("calc completed? "
finished )
53
Suspend / Resume
  • Ada
  • Real-Time Annex defines a package
    Ada.Asynchronous_Task_Control with procedures
    Hold, Continue
  • Hold(T) conceptually sets Ts priority less than
    that of the idle task
  • Effect deferred during protected operations,
    rendezvous
  • Continue(T) restores Ts pre-held priority
  • Java
  • t.suspend() suspends t, without releasing locks
  • t.resume() resumes t
  • These methods have been deprecated
  • If a thread t is suspended while holding a lock
    required by the thread responsible for resuming
    t, the threads will deadlock
  • Arguably this programming bug should not have
    caused the methods to be deprecated
  • POSIX
  • Not supported

54
Comparison of Asynchrony Mechanisms
  • Points of difference
  • Ada attempts a minimalist approach, whereas the
    real-time Java specs (and to some extent POSIX)
    provide more general models
  • Methodology / reliability
  • Asynchronous operations are intrinsically
    dangerous, the goal is to minimize / localize the
    code that needs to be sensitive to disrupti
Write a Comment
User Comments (0)
About PowerShow.com