• Home
  • Textbooks
  • Real-Time Systems and Programming Languages: Ada, Real-Time Java and C/Real-Time POSIX
  • Shared variable-based synchronization and communication

Real-Time Systems and Programming Languages: Ada, Real-Time Java and C/Real-Time POSIX

Alan Burns, Andy Wellings

Chapter 5

Shared variable-based synchronization and communication - all with Video Answers

Educators


Chapter Questions

Problem 1

Show how Peterson's algorithm given in Section 5.2 can be modified to allow a high-priority task to be given preference over a low-priority one when busy waiting.

Check back soon!

Problem 2

Consider a data item which is to be shared between a single producer and a single consumer. The producer is a periodic task which reads a sensor and writes the value to the shared data item. The consumer is a sporadic task which wishes to take the latest value placed in the shared data item by the producer.
The following package claims to provide a generic algorithm with which the producer and consumer can communicate safely, without the need for mutual exclusion or busy waiting.
generic
type Data is private;
Initialvalue : Data;
package Simpsons_Algorithm is
procedure Write(Item: Data); -- non-blocking
procedure Read (Item : out Data); -- non-blocking
end Simpsons_Algorithm;
package body Simpsons_Algorithm is
type slot is (First, Second);
Fourslot : array (Slot, Slot) of Data :=
(First $\Rightarrow$ (Initialvalue, Initialvalue),
Second $=>$ (Initialvalue, Initialvalue));
Nextslot : array(Slot) of slot := (First, First);
Latest : Slot : = First;
Reading : Slot := First;
procedure Write(Item : Data) is
Pair, Index : Slot;
begin
if Reading $=$ First then
Pair := Second;
else
Pair := First;
end if;
if NEXT_SLOT (Pair) = First then
Index := Second;
else
Index := First;
end if;
Fourslot(Pair, Index) $:=$ Item;
Nextslot(Pair) := Index;
Latest : = Pair;
end write;
procedure Read(Item : out Data) is
Pair, Index : Slot;
begin
Pair : = Latest;
Reading := Pair;
Index := Nextslot(Pair);
Item := Fourslot(Pair, Index);
end Read;
end Simpsons_Algorithm;

Describe carefully how this algorithm works by explaining what happens when:
(1) a Write is followed by a Read
(2) a Read is preempted by a Write
(3) a Write is preempted by a Read
(4) a Read is preempted by more than one Write
(6) a Write is preempted by more than one Read

Comment on how the algorithm trades off safe communication against data freshness.
Many compilers optimize code so that frequently accessed variables are held in registers local to a task. In this context, comment on whether the above algorithm's claim of safe communication is justifiable. Are there any changes to the algorithm needed to make it work for all implementations of Ada?

Check back soon!

Problem 3

Consider a shared data structure that can be both read from and written to. Show how semaphores can be used to allow many concurrent readers or a single writer, but not both.

Check back soon!

Problem 4

Show how Conditional Critical Region can be implemented using semaphores.

Check back soon!

Problem 5

Show how Hoare's monitors can be implemented using semaphores.

Check back soon!

Problem 6

Show how binary semaphores can be implemented using Hoare's monitors.

Check back soon!

Problem 7

One of the criticisms of monitors is that condition synchronization is too lowlevel and unstructured. Explain what is meant by this statement. A higher level monitor synchronization primitive might take the form
Waituntil boolean_expression;
where the task is delayed until the boolean expression evaluates to true. For example:

Waituntil $x<y+5$;
would delay the task until $x<y+5$.
Although this form of condition synchronization is more structured it is not found in most languages which support monitors. Explain why this in the case. Under what circumstances would the objections to the above high-level synchronization facility be invalid? Show how the bounded buffer problem can be solved using the waitUntil synchronization primitive inside a monitor.

Check back soon!
02:30

Problem 8

Consider a system of three cigarette smoker tasks and one agent task. Each smoker continuously makes a cigarette and smokes it. To make a cigarette three ingredients are needed: tobacco, paper and matches. One of the tasks has paper, another tobacco and the third has matches. The agent has an infinite supply of all three ingredients. The agent places two ingredients, chosen randomly, on a table. The smoker who has the remaining ingredient can then make and smoke a cigarette. Once it has finished smoking the smoker signals the agent who then puts another two of the three ingredients on the table, and the cycle repeats.
Sketch the structure of a monitor which will synchronize the agent and all three smokers.

Daniel Caproni
Daniel Caproni
Numerade Educator

Problem 9

Show how the operations on a semaphore can be implemented in the nucleus of an operating system for a single processor system without busy waiting. What hardware facility does your solution require?

Check back soon!

Problem 10

Show how C/Real-Time POSIX mutexes and condition variables can be used to implement a shared data structure that can be both read from and wrítten to. Allow many concurrent readers or a single writer but not both.

Check back soon!

Problem 11

Show how C/Real-Time POSIX mutexes and condition variables can be used to implement a resource controller.

Check back soon!

Problem 12

Complete Exercise 4.8 using Ada's protected objects for task synchronization.

Check back soon!

Problem 13

Compare and contrast the facilities provided by the C/Real-Time POSIX mutexes and condition variables with those provided by Ada's protected objects.

Check back soon!

Problem 14

Redo Exercise 5.8 using protected objects.

Check back soon!

Problem 15

Implement quantity semaphores using protected objects.

Check back soon!

Problem 16

Show how one or more protected objects can be used to implement Hoare's monitors.

Check back soon!

Problem 17

Explain the synchronization imposed by the following Ada protected object:
protected type Barrier(Needed : Positive) is
entry Wait;
private
Releasing : Boolean := False;
end Barrier;
protected body Barrier is
entry Wait when Wait'Count = Needed or Releasing is
begin
if Wait'count $=0$ then
Releasing = False;
else
Releasing := True;
end if;
end Wait;
end Barrier;

The following package provides a simplified Ada binding to Real-Time POSIX Mutexes and Condition Variables. All Mutexes and Condition Variables are initialized with default attributes.
package Pthreads is
type Mutex_T is limited private;
type cond_T is limited private;
procedure Mutex_Initialize (M: in out Mutex_T);
procedure Mutex_Lock(M: in out Mutex_T);
procedure Mutex_Trylock (M: in out Mutex_T);
procedure Mutex_Unlock(M: in out Mutex_T);
procedure Cond_Initialize(C: in out Cond_T);
procedure Cond_Wait (C: in out Cond_. $T$;
$\mathrm{M}$ : in out Mutex_T);
procedure Cond_Signal (C: in out Cond_T);
procedure Cond_Broadcast (C: in out Cond_T);
private
. . .
end Pthreadis;

Show how Barriers, as defined above, can be implemented using this package. Do not use any of Ada's communication and synchronization facilities in the solution.

Check back soon!

Problem 18

The following package defines an Ada semaphore abstraction:
generic
Initial : Natural:= 1; -- default initial value of semaphore
package Semaphore_Package is
type Semaphore is limited private;
procedure Wait (S : Semaphore);
procedure Signal (S : Semaphore);
private
type Semaphore is ...; ... not needed for this question
end Semaphore_Package;
Using the Semaphore_Package, show how the following communication paradigm (and its associated package specification) can be implemented.
A Multicast is where one task is able to send the same data to several waiting tasks. A package specification for the Multicast abstraction is given below:
package Multicast is
procedure Send (I ; Integer);
procedure Receive (I : out Integer\};
end Multicast;
The receiver tasks indicate their willingness to receive data by calling the procedure Receive defined in the package given above (in this example the data is of type Integer). The tasks are blocked by this call. A sender task indicates that it wishes to multicast data by calling the Send procedure. All tasks which are currently blocked on the receive are released when the sender invokes the Send procedure. The data passed by the sender is given to all waiting tasks. Once the Send procedure has finished, any new calls to Receive must wait for the next sender.
Show how the body of the Multicast package can be implemented using semaphores.

Check back soon!

Problem 19

A broadcast is similar to a multicast except that ALL intended recipients must receive the data. A package specification for the Broadcast abstraction is given below:
package Broadcast is
-- for 10 tasks
procedure Send (I : Integer);
procedure Receive(I : out Integer);
end Broadcast;
Consider, for example, a system with 10 recipient tasks. These tasks all call the Receive procedure when they are ready to receive the broadcast. The tasks are blocked by this call. A sender task indicates that it wishes to broadcast data by calling the Send procedure. The Send procedure waits until all ten tasks are ready to receive the broadcast before releasing the recipients and passing the data. If more than one call to Send occurs, then they are queued.
Show how the body of the Broadcast package can be implemented using the semaphore package given in Exercise 5.18.

Check back soon!
03:02

Problem 20

It has been suggested that York should put a limit on the number of motorists that can enter the city at any one time. One proposal is to establish monitoring checkpoints at each of the city's Bars (entrances through the city's walls) and, when the city is full, to turn the traffic lights to red for incoming traffic. To indicate to the motorists that the city is full, the red light is set to flashing.
In order to achieve this goal, pressure sensors are placed in the road at the Bars' entry and exit points. Every time a car enters the city, a signal is set to a BarController task (as a task entry call); similarly when a car exits:
Max_Cars_In_City_For_Red_Light : constant Positive $:=\mathrm{N}$;
Min_Cars_In_City_For_Green_Light : constant Positive $:=\mathrm{N}-10$;
type Bar is (Walmgate, Goodramgate, Micklegate,
Bootham, Barbican);
task type Bar_Controllex(G : Bar) is
entry Car_Entered;
entry Car_Exited;
end Bar_Controller;
Walmgate_Bar_Controller : Bar_Controller(Walmgate);
Goodramgate_Bar_Controller : Bar_Controller(Goodramgate) ;
Micklegate_Bar_Controller : Bar_Controller(Micklegate) ;
Boothan_Bar_Controller : Bar_Controller(Bootham) ;
Barbican_Bar_Controller : Bar_Controller(Barbican) ;

Show how the body of these tasks can be coordinated so that ONE of them calls the CityTrafficLightController (with the following task specification) to indicate whether more cars are to be allowed in or not.
task City_Traffic_Lights_Controller is
entry City_Is_Full;
entry City_Has_Space;
end City_Traffic_Lights_Controller;
task body Traffic_Lights_Controller is separate;
-. body of no interest in this question

Vishal Gupta
Vishal Gupta
Numerade Educator
02:09

Problem 21

Explain why the resource controller given in Section 5.4.7 suffers from a race condition. How can the algorithm be modified to remove this condition?

Caitlyn Hobbins
Caitlyn Hobbins
Numerade Educator

Problem 22

Show how the reader/writers problem can be implemented in Java where priority is given to readers and where writers are guaranteed to be serviced in a FIFO order.

Check back soon!

Problem 23

Show how Java can be used to implement a resource controller.

Check back soon!

Problem 24

Implement quantity semaphores using Java.

Check back soon!

Problem 25

Consider the following Java class:
public class Event \{
public synchronized void highPriorityWait();
public synchronized void lowPriorityWait();
public synchronized
void signalEvent();
\}
Show how this class be implemented so that signalEvent releases one highpriority waiting thread if one is waiting. If there is no high-priority waiting thread, release one low-priority waiting thread. If no thread is waiting, the signalEvent has no effect.
Now consider the case where an Id can be associated with the methods. How can the algorithm be modified so that the signalEvent wakes up the appropriate blocked thread?

Check back soon!