Assignment 8 for CSCI 431

Background on Running Ada

Remember that the gnat compiler for Ada has been installed on Burnsville. For more information on using that compiler, see assignment 4.

Overview

Ada tasks execute concurrently. On a multiprocessor computer, the tasks may execute in parallel (simultaneously). On a single processor computer their execution may be interleaved, with the Ada run-time system scheduling and dispatching the tasks. In this exercise you will investigate some of the issues involved in using concurrent tasks which access shared variables.

Part 1

Study the package in the files buftask.ads and buftask.adb The specification indicates that there are 2 tasks, WriteChar and ReadChar. The tasks execute concurrently and are used to write and read characters to and from a buffer. The body of the package shows that the buffer is a queue, using a circular array implementation.

Examine the code and notice that select statements with guards are used to ensure that WriteChar does not write to a full buffer and ReadChar does not read from an empty buffer.

The buffer is a resource shared by the tasks. When modifying the variables which implement the buffer, a task is in a critical region. It must be given exclusive access to the buffer, but this is not provided by the package.

The program in the file driver.adb uses the buftask package. Notice that there are Writer and Reader tasks which rendezvous with the task implementing the buffer. Writer writes a character string to the buffer, while Reader reads from the buffer and prints its contents to standard output, starting a new line of output whenever a '.' or '$' is encountered.

When compiled and run with a properly implemented buffer, the output of the program should be:


   this is line 1.
   this is line 2.
   and this is line 3$
and then the program should hang while Reader is waiting to read more characters from the buffer.

Compile the buftask package and driver.adb using the Makefile provided here. Execute the driver program, and observe the output. Do not halt the execution prematurely.

Turn in an explanation of what the program did when you executed it, and why.

Part 2

Synchronize the access of WriteChar and ReadChar to the buffer by using a binary semaphore. Modify the code for the buftask package making the semaphore task local to the package body.

Recompile buftask and driver and run the program. With WriteChar and ReadChar given exclusive access to the buffer variables, the output should now be correct.

Turn in a hardcopy of the modified buftask package.