From: Craig Carey <research@ijs.co.nz>
Subject: Re: problem of read and write
Date: Fri, 13 Dec 2002 15:03:24 +1300
Date: 2002-12-13T15:03:24+13:00 [thread overview]
Message-ID: <eafivucl5ep8bvqg2djip40aoaous4q62f@4ax.com> (raw)
In-Reply-To: slrnave1q7.jk.lutz@taranis.iks-jena.de
On Wed, 11 Dec 2002 09:37:12 +0000 (UTC), Lutz Donnerhacke <lutz@iks-jena.de> wrote:
>* Francisco Santoyo wrote:
>> I have two tasks, one write[s] in some objects and the other read[s] from
>> them.
>>
>> How can I avoid th[is:] the reader task read[s] the first object before...
>> the writer task [has] finish[ed]... writ[ing the first, some, or] the last?.
>
>Depending on your problem you can collect all those objects into a protected
>type or use a semaphore (also a protected type) to synchonize a long term
>access.
A sample program of reading and writing appears below.
This was my entry for the Computer Language Shootout contest of the
www.bagley.org website. The entry was rejected by a brief note I got in the
last week with the reasoning xplaining that the contest had closed last year.
The code here would be a solution to the Producer Consumer example of the
constest; and that example has a webpage here:
http://www.bagley.org/~doug/shootout/bench/prodcons/
-------------------------------------------------------------------------------
with Text_IO, Ada.Command_Line; -- Ref. http://www.bagley.org/~doug/shootout/
procedure Prodcons is -- 11-Dec-2002, coded in Ada 95
type Buffer_Array is array (Positive range <>) of Integer;
type Buffer_Array_Ptr is access Buffer_Array;
Buffer : Buffer_Array_Ptr; -- Initialised to null
Buffer_Closed_Error : exception;
protected Controller is
entry Sample (Boolean) (Data : in out Integer);
procedure Finish_Up; -- (Calls don't queue on protected procedure)
private -- (Guards can be not updated when
Count : Integer := 0; -- only global variables change)
Closed : Boolean := False;
end Controller;
protected body Controller is -- A family entry instead of 2 entries
entry Sample (for Put_Not_Get in Boolean) (Data : in out Integer)
when (Put_Not_Get and Count = 0) or -- Block with 0% CPU use
((not Put_Not_Get) and (Count /= 0 or Closed)) is
begin
if Put_Not_Get then -- Add to the buffer
Count := Count + 1;
Buffer (Count) := Data;
elsif Closed and Count = 0 then
raise Buffer_Closed_Error; -- Raise an exception
else -- Take from buffer
Data := Buffer (Count);
Count := Count - 1;
end if;
end Sample;
procedure Finish_Up is begin Closed := True; end Finish_Up;
end Controller;
Consumed, Produced : Natural := 0;
N, T1, T2, Chk : Integer := 0;
begin
if Ada.Command_Line.Argument_Count >= 1 then
begin
N := Natural'Max (0, Integer'Value (Ada.Command_Line.Argument (1)));
exception -- RM3.5(44) allows N to be negative if X'Max is omitted
when Constraint_Error => N := 1;
end;
end if;
Buffer := new Buffer_Array (1 .. N); -- N can be 0 (and -1 would be OK)
declare
task Producer; task Consumer; -- The tasks start when declared
task body Producer is
begin
for I in 1 .. N loop
T1 := I; -- (I is constant)
Controller.Sample (True) (Data => T1);
Produced := Produced + 1; Chk := Chk + I ** 3;
end loop; -- Chk is OK despite overflow, no -gnato
Controller.Finish_Up;
end Producer;
task body Consumer is
begin
loop
begin
Controller.Sample (False) (Data => T2);
Consumed := Consumed + 1; Chk := Chk - T2 ** 3;
exception
when Buffer_Closed_Error => exit; -- Exit the loop
end;
end loop; -- No "exit when K=N;" at bottom, to save a line
end Consumer; -- and the requirements seemed to allow that
begin
null; -- Wait here until the tasks have finished
end;
if Chk /= 0 then Text_IO.Put_Line ("Program_Error"); end if; -- No probs
Text_IO.Put_Line ("N =" & Integer'Image (N) & ": Produced =" & Natural'
Image (Produced) & ", Consumed =" & Natural'Image (Consumed));
end Prodcons;
-------------------------------------------------------------------------------
That program seems to take about 12.7 secs per 1000 MHz of CPU power to get the
variable 'Produced' incremented up to 1,000,000, in Windows 2000 GNAT (with the
-O2 option), which seems very fast (at 12.7 microseconds), but it was not
ranking in the top 3.
THe Gcc entry has a loop around a mutex wait. Does someone know if that it is
actually a correct way to code when the operating system time slice interval is
bigger than 10 seconds. The Gcc entry did not contain any code to reduce the
operating system time slice interval thus I am unclear on whether it had a bug.
Craig Carey <research@ijs.co.nz>
Ada 95 mailing lists; http://www.ijs.co.nz/ada_95.htm
next prev parent reply other threads:[~2002-12-13 2:03 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.1039593002.2252.comp.lang.ada@ada.eu.org>
2002-12-11 9:37 ` problem of read and write Lutz Donnerhacke
2002-12-13 2:03 ` Craig Carey [this message]
2002-12-13 4:51 ` Dennis Lee Bieber
2002-12-13 21:45 ` Dennis Lee Bieber
2002-12-13 8:19 Grein, Christoph
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox