From: "Steve" <nospam_steved94@comcast.net>
Subject: Re: Ravenscar-compliant bounded buffer
Date: Tue, 4 Sep 2007 20:00:13 -0700
Date: 2007-09-04T20:00:13-07:00 [thread overview]
Message-ID: <GKadnVsMGJJdhkPbnZ2dnUVZ_hadnZ2d@comcast.com> (raw)
In-Reply-To: 1188914005.607732.277400@57g2000hsv.googlegroups.com
While I don't know much about the Ravenscar profile (other than what it is)
I am famialar with the use of protected types.
The sample code is a good illustration of "abstraction inversion". I know
this because I posted similar code on this group several years ago and that
is how it was described.
The code uses a high level abstraction "protected type" to create a low leve
abstraction "Binary_Semaphore". The code uses two semaphores to restrict
access to the bounded buffer. In this simple example it is easy to follow,
but in a more complex example pairing Acquire's and Release's can be a
chore.
Consider an alternate implementation:
-- bounded_buffer.ads
package Bounded_Buffer is
type Buffer_Type is limited private;
procedure Put (Buffer : in out Buffer_Type; Item : in Integer);
procedure Get (Buffer : in out Buffer_Type; Item : out Integer);
private
protected type Exclusive_Access is
entry Put (Buffer : in out Buffer_Type; Item : in Integer);
entry Get (Buffer : in out Buffer_Type; Item : out Integer);
private
Available_For_Reading : Boolean := False;
Available_For_Writing : Boolean := True;
end Exclusive_Access;
type Buffer_Type is limited record
Storage : Integer;
Protected_Access : Exclusive_Access;
end record;
end Bounded_Buffer;
-- bounded_buffer.adb
package body Bounded_Buffer is
protected body Exclusive_Access is
entry Put (Buffer : in out Buffer_Type; Item : in Integer) when
Available_For_Writing is
begin
Buffer.Storage := Item;
Available_For_Reading := True;
Available_For_Writing := False;
end Put;
entry Get (Buffer : in out Buffer_Type; Item : out Integer) when
Available_For_Reading is
begin
Item := Buffer.Storage;
Available_For_Reading := False;
Available_For_Writing := True;
end Get;
end Exclusive_Access;
procedure Put (Buffer : in out Buffer_Type; Item : in Integer) is
begin
Buffer.Protected_Access.Put( Buffer, Item );
end Put;
procedure Get (Buffer : in out Buffer_Type; Item : out Integer) is
begin
Buffer.Protected_Access.Get( Buffer, Item );
end Get;
end Bounded_Buffer;
----------------------------------
Here a single Exclusive_Access protected type is used to restrict access to
the buffer.
It avoids the situation that you will run into with "who's not releasing the
semaphore".
BTW: I apologize for my choice of type and variable names, I didn't spend
much time thinking about them.
Regards,
Steve
(The Duck)
"Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message
news:1188914005.607732.277400@57g2000hsv.googlegroups.com...
> In one of my previous posts I have criticized example 12 from the
> Ravenscar document.
> It makes sense to criticize constructively, I think. :-)
>
> -- bounded_buffer.ads
> package Bounded_Buffer is
>
> type Buffer_Type is limited private;
>
> procedure Put (Buffer : in out Buffer_Type; Item : in Integer);
> procedure Get (Buffer : in out Buffer_Type; Item : out Integer);
>
> private
>
> protected type Binary_Semaphore (Initial_State : Boolean) is
> entry Acquire;
> procedure Release;
> private
> Available : Boolean := Initial_State;
> end Binary_Semaphore;
>
> type Buffer_Type is limited record
> Storage : Integer;
> Available_For_Reading : Binary_Semaphore (Initial_State =>
> False);
> Available_For_Writing : Binary_Semaphore (Initial_State =>
> True);
> end record;
>
> end Bounded_Buffer;
>
> -- bounded_buffer.adb
> package body Bounded_Buffer is
>
> procedure Put (Buffer : in out Buffer_Type; Item : in Integer) is
> begin
> Buffer.Available_For_Writing.Acquire;
> Buffer.Storage := Item;
> Buffer.Available_For_Reading.Release;
> end Put;
>
> procedure Get (Buffer : in out Buffer_Type; Item : out Integer) is
> begin
> Buffer.Available_For_Reading.Acquire;
> Item := Buffer.Storage;
> Buffer.Available_For_Writing.Release;
> end Get;
>
> protected body Binary_Semaphore is
>
> entry Acquire when Available is
> begin
> Available := False;
> end Acquire;
>
> procedure Release is
> begin
> Available := True;
> end Release;
>
> end Binary_Semaphore;
>
> end Bounded_Buffer;
>
> -- test.adb
> with Ada.Text_IO;
> with Bounded_Buffer;
>
> procedure Test is
>
> Buffer : Bounded_Buffer.Buffer_Type;
>
> task Writer;
> task body Writer is
> begin
> for I in 1 .. 50 loop
> Bounded_Buffer.Put (Buffer, I);
> end loop;
>
> Bounded_Buffer.Put (Buffer, 0);
> end Writer;
>
> task Reader;
> task body Reader is
> I : Integer;
> begin
> loop
> Bounded_Buffer.Get (Buffer, I);
> exit when I = 0;
> Ada.Text_IO.Put (Integer'Image (I));
> Ada.Text_IO.New_Line;
> end loop;
> end Reader;
>
> begin
> null;
> end Test;
>
>
> I would like to ask you to comment/criticize on the above.
> (The test.adb driver is provided just to sanity-check the rest.)
>
> Note that in this example the shared data (Storage component of the
> Buffer object) is accessed directly from concurrent subprograms.
> Protecting this access is not necessary on the basis that binary
> semaphores provide necessary exclusion and signalling (ordering). With
> buffer of capacity > 1 the storage array and top/bottom indices would
> be encapsulated by another protected object.
>
> --
> Maciej Sobczak
> http://www.msobczak.com/
>
next prev parent reply other threads:[~2007-09-05 3:00 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-09-04 13:53 Ravenscar-compliant bounded buffer Maciej Sobczak
2007-09-05 3:00 ` Steve [this message]
2007-09-05 7:38 ` Maciej Sobczak
2007-09-06 4:04 ` Steve
2007-09-06 14:06 ` Robert A Duff
2007-09-06 15:36 ` Dmitry A. Kazakov
2007-09-07 2:36 ` Robert A Duff
2007-09-06 21:13 ` Maciej Sobczak
2007-09-07 2:41 ` Robert A Duff
2007-09-07 11:56 ` anon
2007-09-07 19:44 ` Maciej Sobczak
2007-09-08 0:16 ` anon
2007-09-08 1:19 ` Larry Kilgallen
2007-09-08 5:13 ` anon
2007-09-08 22:06 ` Larry Kilgallen
2007-09-09 2:17 ` anon
2007-09-09 12:07 ` Larry Kilgallen
2007-09-09 13:10 ` Markus E L
2007-09-11 2:44 ` Randy Brukardt
2007-09-08 11:50 ` Niklas Holsti
2007-09-08 12:01 ` Pascal Obry
2007-09-08 17:13 ` anon
2007-09-08 17:11 ` anon
2007-09-08 19:14 ` Markus E L
2007-09-09 14:54 ` anon
2007-09-09 16:01 ` Markus E L
2007-09-09 10:38 ` Gautier
2007-09-09 11:41 ` anon
2007-09-09 13:19 ` Markus E L
2007-09-09 13:52 ` Pascal Obry
2007-09-09 15:22 ` anon
2007-09-09 16:03 ` Markus E L
2007-09-10 0:05 ` Larry Kilgallen
2007-09-10 3:10 ` Markus E L
2007-09-09 16:05 ` Markus E L
2007-09-09 18:40 ` Ed Falis
2007-09-09 19:11 ` Markus E L
2007-09-09 10:57 ` Gautier
2007-09-09 14:49 ` anon
2007-09-09 15:08 ` Pascal Obry
2007-09-09 15:38 ` Markus E L
2007-09-09 19:12 ` Niklas Holsti
2007-09-09 19:28 ` Ed Falis
2007-09-10 12:51 ` Colin Paul Gloster
2007-09-07 1:38 ` Steve
2007-09-07 2:47 ` Robert A Duff
2007-09-05 7:46 ` Dmitry A. Kazakov
2007-09-05 8:17 ` brodax
2007-09-05 8:30 ` Jean-Pierre Rosen
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox