Semaphore in Ada

Viewed 3375

This is an assignment and I have been asked to implement a Semaphore in Ada as the description below.

However I have implemented the Semaphore.adb and called this Semaphore in the producerconsumer_sem.adb which I created.

I get some output which is the following.

  1. I'm not sure if my initialization of semaphore is correct S: CountingSemaphore(1,1);.

  2. I don't know where I call the S.wait and S.Signal now i randomly called the S.wait before Producer put item in the buffer X := I; and the S.Signal after the X := I;. Is this the correct way?

Producer-Consumer Problem The program producerconsumer.adb implements a non-reliable implemen- tation of the producer-consumer problem, where data is likely be lost. In the following, you will use three different communication mechanisms to achieve a reliable implementation of the producer-consumer problem.

Semaphore

The Ada language does not directly provide library functions for a semaphore. However, semaphores can be implemented by means of a protected object. Create a package specification Semaphore in the file Semaphores.ads and the corresponding package body in the file Semaphores.adb that implements a counting semaphore. Skeletons for the package are available on the course page.

Use the semaphore package for a reliable implementation of the producer- consumer problem. Modify the file producerconsumer.adb and save the final code as producerconsumer_sem.adb. In order to use the semaphore package it shall be installed in the same directory as producerconsumer_sem.adb. It can then be accessed by

with Semaphores; use Semaphores;

The Output:

OutPut: 1 1 1 2 2 3 4 4 5 6 6 7 7 8 9 9 9 10 11 11 11 12 12 13 13 13 14 15 15 16 16 17 18 18 18 19 20 20 21 21 22 22 23 24 24 24 24 25 25 26 27 27 28 29 29 30 30 31 31 32 32 33 33 33 34 35 35 35 36 36 37 37 37 38 38 38 39 40 40 40

The package

package Semaphores is
   protected type CountingSemaphore(Max: Natural; Initial: Natural)  is
      entry Wait;
      entry Signal;
   private
      Count : Natural := Initial;
      MaxCount : Natural := Max;
   end CountingSemaphore;
end Semaphores;

The Semaphore I implemented semaphores.adb.

package body Semaphores is
   protected body CountingSemaphore is
   entry Wait when Count > 0 is
    begin
    Count := Count - 1;

    end Wait;
      entry Signal when Count < MaxCount is
    begin
    Count := Count + 1;

    end Signal;
   end CountingSemaphore;
end Semaphores;

The producerconsumer_sem.adb

with Ada.Text_IO;
use Ada.Text_IO;

with Ada.Real_Time;
use Ada.Real_Time;

with Ada.Numerics.Discrete_Random;

with Semaphores;
use Semaphores;

procedure ProducerConsumer_sem is

   X : Integer; -- Shared Variable
   N : constant Integer := 40; -- Number of produced and comsumed variables

   S: CountingSemaphore(1,1);
   --S1: CountingSemaphore(1,1);

   pragma Volatile(X); -- For a volatile object all reads and updates of
                       -- the object as a whole are performed directly
                       -- to memory (Ada Reference Manual, C.6)

   --Random Delays
   subtype Delay_Interval is Integer range 50..250;
   package Random_Delay is new Ada.Numerics.Discrete_Random
   (Delay_Interval);
   use Random_Delay;
   G : Generator;

   task Producer;

   task Consumer;

   task body Producer is
      Next : Time;
   begin
      Next := Clock;
      for I in 1..N loop
         -- Write to X
         S.Wait;
         X := I;
         S.Signal;
         --Next 'Release' in 50..250ms
         Next := Next + Milliseconds(Random(G));
         Put_Line(Integer'Image(X));
         delay until Next;
      end loop;
   end;

   task body Consumer is
      Next : Time;
   begin
      Next := Clock;
      for I in 1..N loop
         -- Read from X
         S.Wait;
         Put_Line(Integer'Image(X));
         S.Signal;
         Next := Next + Milliseconds(Random(G));
         delay until Next;
      end loop;
   end;

begin -- main task


   null;
end ProducerConsumer_sem;
1 Answers
Related