You are on page 1of 15

Intertask Cornmunication andSynchronization

KEY POINTS OF THE CHAPTER 1. Double buffering is an effective technique for producer/consumer scenarioswhere data need to be passedin a time-correlatedfashion. * Critical regions are sectionsof code accessing serially reusableresources. Critical sectionsmust be given special consideration. 3. Semaphores an effective mechanismfor protecting critical regions. are 4. Mailboxes can be used to implement efficient semaphores" 5. Other mechanismssuch as ring buffers and queuescan be usedto handle more complicated data passing in real-time. 6. Deadlock is a serious problem often introduced by synchronization attempts and must be dealt with in some way. In this chapter we investigate an important problem in any multitasking system: the communication of data between processes and the synchronizationof tasks. Related to these issuesis the problem of sharing certain resourcesthat can only be used by one task at a time. These techniquesneed to be applied in all of the >olutionsdiscussedin the previous chapter.With coroutines,synchronizationand communicationare built into the code, but protection of sharedresourcesis still needed.

Chap. 7 I Intertask Communication and Synchronizaticn


in a multitasking Severalmechanismscan be employed to passdatabetweentasks variables' Globd global system.The simplestand fastestamongtheseis the use of variables,thoughconsideredconffarytogoodsoftwareengineeringprr problems relatedro tice [165], are oitdn used in high-speedoperations.One of the can preempt lower-prioritt using global variables is that tasks of higher priority was discussed routines at inopportunetimes, comrpting the global data.This issue in Chapter 3. per second' Ftr example, one task may produce data at a constant 100 units at irregular intervals, but in 9600-unt whereas another may consumethese data the producer m "{ chunks. In order to provide thesedata to the consuming task, a stack or othcr fill a storageur"u .uil"d a buffer with such data.The buffer can be course, if tbe data struciure, including an unorganized mass of variables. Of fastir than it can be produced,or if th consumertask consumesttris information of consumer cannot keep up with the producer, problems occur. Selection these probk appropriate size buffer ii critical in reducing or eliminating

in is filoff"t sizecalculation discussed Chapter10')

Buffering 7.1.1Time-Relative
ping-pong bull A common use of globat variables is in double buffering or ot corre This techniqueis used when time-relative (also called synchronous when a full set data need to be transferredbetweencycles of different rates,or anotherproct data is neededby one processbut can only be supplied slowly by biocks of data from one device Many telemetry Systems,which transmit swirch another. use double-buffering schemeswith a hardware or software g altemate the buffers. This strategy is also used in ,disk controllers' places' interfaces,navigation equipment, robot controls, and many other
the image is completed. [n In certain graphics processes, lines are drawn one by one until


on oneso we If, ,irtr., ,o. do not want to seethis drawingprocess. however. draw animated when the new drawing is complea flip the screens imagewhiie displayingthe other and then
Switchwith interruptsdisabled

Bulfor 1

Buffei 2

Figure 7.1 Double buffering.


Bufferine Data


individual line drawing commandswill not be seen.If the screenscan be updatedat about 30 screens per second,the image will appearfully animated.SeeFigure 7.1. I

As an example of time-re'lativebuffering, consider the following. I EXAMPLE 7.2
pulsesin a S-mrllisecond cycle.Thesedata are A navigationsystemreads,r,H and z accelerometer to be processed a lO-millisecond in cycle which haslower prioriry than the 5-millisecondcycle (i.e., in it can be preempted). The accelerometer data processed the l0-millisecond cycle must be timepulsesfrom time r along with z relative;that is, we do not wish to process and y accelerometer x pulsesfrom time t + 1. This could occur if the 10-millisecond cycle has completed accelerometer processing the;r and y data,but gets interruptedby the 5-millisecondcycle To avoid this problem, we use buffered variablesxb, yb, and zb in the l0-millisecond cycle and buffer them, with intemrpts disabled.The l0-millisecond routine mieht look like this in C: introf ( ) ; x b = x ; Y b = Y ;
zI; z. / * ^ i c : l l , o i n F o - r r r n r c * ;






() ;
/vh rr)^' zh\


enable interrupts



In practice, the first procedurein any cycle would be a buffering routine to buffer all datafrom tasksof higher priority into the current task ("buffer in" routine). The last procedurp in the cycle is a routine to buffer out data to any tasks of lower priority ("buffer out" routine).

12 Ring Buffers
A special data structurecalled a circular queueor ring buffer is used in the same way as a first-irVfirst-out list. Ring buffers, however, are easier to manage. In the ring buffer, simultaneousinput and output to the list are achievedby keeping head and tail pointers. Data are loaded at the tail and read from the head. Figure 7.2 illustrates this. An implementation of the "read(data,S)" and "write(data,S)" operations, which read from and write to ring buffer S, respectively,are given below in Pascalcode. It is assumedthat the buffer has a size ofN and that head and tail have been initiali?ed to 0.
: l:i.f e
ra=Alttar d:f: . infaaar Q . arr:rrfO NT-1I , n- f i- n -| -- -a-d a r ' -I i

head=tai1 then data : = nulf e 1s e
l ^ r ^

t underfLow


head end

S lhead] ; (head+1)

mod N

data from buffer { retrieve } { decrement head pointer

172 procedure begin if data :

Chap. 7 I

Intertask Communication and Synchronizatim


i nts6d6r

. .

rrrrrrIO srrqt


T . r\ r - 1 f l I

nf v!

i r fusY r n r a n a r! \!


( t a i l + 1 ) m o d N = head then error i else begin Sltaill := data; tail := (tai1+1) mod N end

{ overflow,





i take

care of wrap-around



Additional code is neededto test for the overflow condition in the ring buffer. overflow occurs when an attempt is made to write data to a full Implementation of this is left as an exercise. Ring buffers can be usedin conjunction with a counting or binary (see next section) to control multiple requests for a single resource such for fnemory blocks, modems,and printers. Requests the resourceare placed d 'tail of the list, while a special processcalled a server services the requests reading the list from the head.

Figure 7.2 Ring buffer.





Mailboxes ot message are exchanges an intertaskcommunicationdevice available in many commercial, full-featured operating systems.They can also be used like :emaphores(next section) but with important advantages. A mailbox is a mutually agreed upon memory location that two or more taskscan use to pass data. The tasks rely on the central schedulerto allow them to write to the location via a post operationor to read from it via a pend operation. The differencebetweenthe pend operation and simply polling the mailbox is that tbe pending task is suspended while waiting for data to appear.Thus, no time is r,asted continually checking the mailbox; that is, the busy waiting condition is eliminated.The data that arepassedcan be a flag usedto protect a critical resource (celled key),they can be a single piece of data, or they can be a pointer to a larger ierr 5ausnrle such as a list or an array-. most implementations,when the key is In from the mailbox, the mailbox is emptied.Thus, although severaltasks can on the same mailbox, only one task can receive the kev. Since the kev nts access a critical resource, to simultaneous access precluded. is We caridescribe the mailbox operations,pend(data,S) andpost(data,S),as








- ^ -=


of mailbox
C J . .

S if

{ r

suspend task
m : i ! r , lv h n v r L r q ^ e e d s6u fr y

c d d. L qr ,^l ^ e r


h ^ - F / t r - r -JVDL\VqI

i - F l UALer

i f lnr fLounv a r! \/ e

are bestimplementedin systemsbasedon the task-controlblock model e srpervisor task. A table containing a list of tasks and neededresources ,nailboxes, printers, etc.) is kept along with a secondtable containing a list and their states.In Tables 7.1 and 7.2, for example, three resources

erist. a printerandtwo mailboxes. printeris bein! usedby task100, The
1 is being used (currently being read from or written to) by task l0l is pending on mailbox I and is suspendedbecause it is not Uailbox 2 is currently not being used or pended on by any task. tbe supervisor is invoked by a system call or hardware intemrpt, it tables to see if some task is pending on a mailbox. If the key is
TABLE 7.1 TaskResource Request Table Taskid # 100 102 lM Resource Printer Mailbox I Mailbox I
Status Has it Has it Pending


Chap. 7 I

Intertask Communication and S

TABLE 7.2 ResourceTable Used in Conjunction with Task ResourceRequestTable

Resource PrinterI Mailbox I Mailbox2 Busy Busy Empty


100 102 None

available (key statusis"full"), then that task must be restarted.Similarly, if e posts to a mailbox, then the operating sysfem must ensurethat the key is in the mailbox and its statusupdated to "full."

7.2.2 OtherOperationson Mailboxes
There are often other operations on the mailbox. For example, in implerneniatiorls,an acceptoperation is permitted.Accept allows tasksto key if-it is available, or immediately retum an error code if the key b available. In other implementations,the pend operutionis equipped with a in out, toprevent deadlocks(which are discussed Chapter 11).

7.2.3 Queues
Some operating systernssupport a type of mailbox that can stack multiple requests.These systems provide qpost, qpend, and qaccept operations to


Ring buffer Figure 7.3 Ring buffer and queues used to control a pool of devices'

Sec. 7.4 I



pend, and accept data toffrom the queue.In this case,the queuecan be regarded as an array of mailboxes, and its implementation is facilitated through the same resourcetablesalreadydiscussed. Queuesshould not be used to pass alrays of data; pointers should be used instead.Queuesare useful in implementing device serverswhere a pool of devices ae involved. Here the ring buffer holds requestsfor a device, and queuescan be used at both the head and the tail to control accessto the ring buffer (seeFigure i. 7--? Such a schemeis useful in the construction of device-controlling software srh as SPOOL (simultaneousperipheral operation on-line) programs, daemons, a in modem pools. (A daemon is a device serverthat does not run explicitly but der lies dormant, waiting for some condition(s) to occur.) ItiOTE 7.1 Queuescan be implementedwith mailboxes-use the mailbox b sreate a counting semaphore(see next section) which restricts accessto an ra1-containing keYs"

systems,we are concernedwith resourcesharing' multitasking/multiprocessing Erostcases,theseresourcescan only be used by one task at a time, and use of cannotbe intemrpted: Such resourcesare said to be serially reusable rEsource drey include certain peripherals, shared memory, and the CPU' While the use, the code that interactswith the other , protectsitself againstsimultaneous ' reusableresourcescannot. Such a code is called a critical region. If two enter the same critical region simultaneously; a catastrophic elror can

eL.. Task_A and Task_B are running in a round-robin system.Task-B will write the message usk_B" and Task_A will write the message"I am Task-A." In the midst of printing, Task-B

by Task-A which beginsprinting.The resultis:
: 1-- I am Task-A Task-B

rrntrus complications could arise if both tasks were accessingmore important devices. I

Simultaneous use of a serial reusable resource is called a collision. Out rhen. is to provide a mechanismfor preventing collisions.

by for protecting citical regions was suggested Dijkstra[34] ,es a special variable called a semaphor€, and two operationson that


Chap. 7 I

Intertask Communication and Synchronizatio

yet they primitives. semaphoresappear to be simple' variable called semaphore aresubtlycomplex.Athoroughunderstandingoftheirnuancesisessential semaphoreS lead to t"tioioot.qllot^"I:i.o avoid implanting logic;;;;?"

n') The primitive operations are defined

Procedure P(var begrn

S : boolean);

rx ;il
' l I

whileS=TRUEdo; S := TRUE end : boolean); Procedure V(var S begrn S : = FALSE end


i, l

r 1

prc The wait operation suspends any signal operation st FALSE, whereasthe b' enters a critical region is bracketed more than one process from entering ExamPle 7.4. 7.4 I EXAMPLE in processes a multitaskinC two :y::T:,^B:*:-:":'":1t"t*:?t::11: S Consider concurrent that Note thesemaphore


is process started' i"1"iiiai7.o to FALSEbeforeeither procedure Processl;
procedure Process2;


critical toprotect.the region.

P( s ) . critical


P(S) critical V(S) reglon


7.5 I EXAMPLE as solvetheproblem follows we fo, iurt-A andTask-Basbefore' can

Sec. 7.4 I



procedure begin
D / q l .


n r n n va v u rs r r o d ! v
y !



begin ( "I am Task-A" ) ; write end P(S); ( "I am Task-B" ) ;

write V(S) end


Note that S is initialized to FALSE.


operation (busy-wait) if A processwill spendmuch of its time in wait semaphore a large amount of contention for the resourceis protectedby it. Becausethe wait protection oper;tion involves a repeatedtest of a while loo! condition, semaphore a spin lock. Furtheffnore, in many books the semaphore is sometimes called variable of choice is mutex, emphasizing the fact that mutual exchision is enforced.

and SemaPhores ?.4.1Mailboxes
primitives are not if Mailboxes can be used to implement semaphores semaphore provided bY the operating system. In this case,there is the addedadvantagethat the pend instruction suspends the waiting processrather than actually waiting on the semaphore. 7.6 I EXAMPLE
Use mailboxes to implement semaphores. procedure P(var T : boofean);

temp : boolean; begin Pend(temp,T) ; end procedure begin p o s t ( K E Y ,T ) end { place key in mailbox. ) V(var T : boolean);


NOTE 7.2 The CPU can be viewed as a critical region protected by a mailbox. The disable or DPI instruction takes the "key" from the mailbox, n'hereasthe enable or EPI instruction puts the "key" back'

Chap. 7 I

Intertask Communication and Synchronization

7.4.2 CountingSemaphores

The P and V semaphoreswe have introduced are called binary semaphores because they can take on one of two values. A second kind of semaphore called a counting semaphore or general semaphore can be used to protect pools of resources, or to keep track of the number of free resources' The l semaphore must be initialized to the total number of free resources before I real-time processingcan commence. The new wait and signal semaphore primitives, MP and MV, arc region when the semdesigned to prevent access to a semaphore-protected aphore is less than or equal to zero. \e semaphoreis releasedor signaled by adding 1 to it.
q r

n r n u s u u !r s o p!uaadr r l-ea i n

MaP I \ r a r ! r f \ vq

' r

in -odF r r ri L v Y v _r ,l '


{ multiple



whileS< end
^-nnanrrza l r ! u 9 E u u r s l-ran vuY i r + rn Ma\ / l \r v : r ! r v zu



. . ^ i r


G r

' .

i r r h lr -u e a dva !r /) ,' Y

{ multiple




but Some real-time kernels provide only binary semaphores, you cn
simulate the counting Semaphore with binary semaphores in the followi way, Suppose S and T are binary semaphoresand P(S) and V(S) are the w and signal operations, respectively, on binary semaphores. We can crer counting semaphoreoperations MP(R) and MV(R) on multiple semaphore using binary semaphoresS and T and integer R as follows:
procedure MP(R: integer) begin P(S); i-f R<0 begin V(S); P(T) end; release wait for counter free ] resource] ) then l-ock counter request ] ) ) a resource I multiple wait ]


none available?


i release


Sec.7.4 I

Semaphores procedure MV(R: integer) ; begin P(S);
P . P r l .

I m r r ' l t i n l a c i a n : l I

i f R < = C t h e n V(T) else V(S) end

{ { { {

lock counter } free resource } any task wai\ting icr free resource? give t.haL Lask'-:.e go ahead i coun:e: j

{ release

The integer R keeps track of the number of free resources.Binary semaphoreS Set protectsR, and binary semaphore is usedto protect the pool of resources. T the initial values of S to FALSE, T to TRUE, and R to the number of available resources. The operationof the code is subtly intricate. In the multiple wait routine, we lock the counting variable and decrementit by 1 to indicate a resourcerequest.If enoughresources available(R > = 0), then we simply releasethe counting are variable and proceed.If no lesourcesare free, then we must releasethe counting using the P(T) call. When we return variableand wait until thereis a free resource countingvanable. from the P(T) call, we also free the In the multiple signal routine, we lock the counting variable and increment the coun?'onthe resourcepool. If any processwas pending on the resourcepool (R < = 0), then we signal that process to go ahead using the V(T) call. If no processwas waiting, then we simply releasethe counter.Note that when we give the waiting processthe go ahead,it releasesthe counting variable with the final V(S) call in procedureMP. Finally, it is easy to see that a binary semaphorecan be simulated with a counting semaphoresimply by initializing the counting semaphoreto 1. Ytu should study this code thoroughly by working out examplesfor different initial values of R and different resourcerequest scenarios.

Problemswith Semaphores
Certain problems arise if the operation of testing and subsequently setting a semaphoreis not atomic-that is, unintemrptible. To illustrate the problem, considerthe following example. 7.7 I EXAMPI.E
Supposetwo tasks in a round-robin system with time-slicing are using a resource protected by a binary semaphoreS. The wait instruction discussedin the previous section, procedure P(var S: boolean); begin whileS=TRUEdo; S := TRUE


Chap. 7 I

Intertask Communication and Synchronization

would generateassembly instructions, in 2-addresscode, similar to: @1 LOAD R1, S TEST R1. 1 JEQ

e 1


where "1" is TRUE and "0" is FALSE. Supposethe processusing this semaphoreprimitive were interrupted between the "TEST" and "STORE" instructions. The intemrpting routine, which migir (becau-icuse the sameresource,finds S to be available and begins using it. If this task then suspends say,its time slice ran out) and the intemrpted task resumes,it will still seethe device as free becau:c the old contentsof S are still in Rl. Thus, two tasks attempt to use the sameresourceand a collisicn occurs. This problem may occur infrequently, and so it may be difficult to test and detect. I

7.4.4 The Test-and-Set Instruction
To solve the problem of atomic operationbetweentesting a memory location and storing a specific value in it, some instruction sets provide a test-and-set macroinstruction.The instruction fetchesa word from memory and teststhe high-. order (or other) bit. If the bit is 0, it is set to 1 and stored again, and a condition code of 0 is retumed. If the bit is 1, a condition code of 1 is retumed and no storc is performed. The fetch, test, and store are indivisible. You can implement the wait and signal operationseasily with a test-and-$r instruction.
n trvnv c c sdl ru r r a y u v P1lrar q . .
r r l L L Y e r / t


begin wnlre end
nrnaodrrra \//\r^r q . r i h r a ^ 6 r! \! !. fevy . ,

t e s t _ a n o _ S e E ( 5 ) = l ' H U L ;O o


begin S: =FALSE end

ProcedureP qould generateassemblylanguagecode that may
loop: TANDS S JNE Loop

where TANDS is a test-and-setinstruction. Some machines do not support the TANDS instruction (d.&, a machine).Finally, a semaphore implementationthat floesnot rely on a test instruction was given by Dijkstra in 1968[34], namely,

Sec.7.5 I

Event Flags and Signals


procedure var
f6mn. P^^l o:n

P (var

S: Boolean ) ;







^ ^ t s

* ^ ^ i ^ l


begin repeaL disable;
t s T6 nP n L U L I . -r

v ,




i nf





, -

rnplrtr. /* = FALSE

'u rr rn f f i l Lr fu cr m yn e r r

cnah'l F

i nf prrlrnLS



Of course, disable and enable must be uninterruptibleproceduresor in-line assembiycode.

Certain languagesprovide for synchronization mechanisms called eventflags. Theseconstructsallow for the specification of an event that causesthe setting of some flag. A second process is designed to react to this flag. Event flags in essencerepresentsimulated intemrpts, created by the programmer. Raising the event flag transfers flow-of-control to the operating system, which can then invoke the appropriatehandler. Tasks that are waiting for the occurrenceof an event are said to be blocked. Fgr example,in ANSI-C, the raise and signal facilities are provided. A signal is a type of software intemrpt handler that is used to react to an exception indicated by the raise operation.Both are provided as function calls, which are typically implemented as macros. The following prototype can be used as the front end for an exception handler to react to signal S.
void (*signal(int S, void(*func) (inc) ) ) (int);

When signal S is set, function "func" is invoked. This function representsthe intemrpt handler.The prototype:
int raise (int S);

Raise is used to invoke the processthat reacts to signal S. 7.8 I EXAMPLE
-{\SI-C includes a number of predefined signals neededto handle anomalousconditions suih as overflow, memory accessviolations and illegal instruction, but these sigrals can b€ replaced with


Chap. 7 I

Intertask Communication and Synchronization

user-definedones.The following C code portrays a generic exception handler that reactsto a certain error condition.
+ i - ^ 1 , , t ^


< - lr-g n td i s --

L .rL>

main ( )

void handler(int sig);


( SIGINT, handler)




up to handle signal =*/ */ */

S 1 G I N T* /

' if ( raise(SIGINT) ;

/* do some processing / * a n o m al y d e t e c t e d /* continue processing

) ]
void handler(int sig)

Handled error here



In C, the signal library function call is used to construct intemrpt handlers to react to signals from extemal hardware,and to handle certain traps-such as floating point overflow-by replacing the standardC library handlerswith your own. Exception handling in Ada looks somewhatdifferent. 7.9 I EXAMPLE
Consider an Ada exception handler to determine whether a matrix is singular (its determinantis 01 Assume that a matrix type has been defined, and it can be determined that the matrix is singuh begin calcul-ate determinant


i nn

when SINGULAR I N U M E R I C / E R R O R = > PUT.(" MATRIX [ S S I N G U L A R " ) ; when others => PUT(" FATAL F r r ^ r raise ERROR;
' | '

Sec.7.6 I



Modula-2 also provides a type of event flag that can be used for exception or intemrpt handlers.

Wren tasks are competing for the same set of two or more serially reusable The notion of resources, then a deadlocksituationor deadlyembracemay ensue. deadlockis best illustratedby example. I EXAMPLE 7.10
TASK_A requires resources I and2, as does Task_B. Task_A is in possessionof resource 1 but is waiting on resource 2. Task_B is in possessionof resource 2 but is waiting on resource 1. Neither Task_A nor Task_B will relinquish the resource until its other requestis satisfied. The situation is S illustrated as foilows where two semaphores, and R, are used to protect resource 1 and resource 2, respectively.
Drnna^rrra Trclz .

Procedure begin


P ( S ):
T l e 6 r a c 6 r r r a a 1 .

D / p \ TTca roenrrrao ? -


A is


stuck here

tT^ ^ u - s_r F^ ^ ^ !t#-.^ sDU u+ L c_a 1

stuck here

V(S); v(R)


it Deadlock is a seriousproblem because cannotalways be detectedthrough trthg. In addition, it m4y occur very infrequently,making the pursuit of a known problem difficult. Finally, the solution of the deadlockproblem is by no including significant straightforward and is not without consequences, on real-time pedormance. Starvation differs from deadlockin that at least one proc€ssis satisfying its can satisfy thei? rementsbut one or more are not. In deadlock,no processes becauseall are blocked. Starvation is sometimescalled livelock. Four conditions are necessarvfor deadlock: l. Murual exclusion 2- Circular wait