From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,45660b0456d3a094 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2002-12-12 18:03:26 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!newsfeed-east.nntpserver.com!nntpserver.com!newsfeed1.easynews.com!easynews.com!easynews!nntp2.aus1.giganews.com!nntp.giganews.com!nntp3.aus1.giganews.com!nntp.clear.net.nz!news.clear.net.nz.POSTED!not-for-mail NNTP-Posting-Date: Thu, 12 Dec 2002 20:03:24 -0600 From: Craig Carey Newsgroups: comp.lang.ada Subject: Re: problem of read and write Date: Fri, 13 Dec 2002 15:03:24 +1300 Message-ID: References: X-Newsreader: Forte Agent 1.92/32.572 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Organization: Customer of Mercury Telecommunications Ltd Cache-Post-Path: drone4.qsi.net.nz!unknown@tnt2-176.quicksilver.net.nz X-Cache: nntpcache 2.4.0b5 (see http://www.nntpcache.org/) X-Original-NNTP-Posting-Host: drone4-svc-skyt.qsi.net.nz X-Original-Trace: 13 Dec 2002 15:03:19 +1300, drone4-svc-skyt.qsi.net.nz NNTP-Posting-Host: 203.97.37.6 X-Trace: sv3-wGmkSK+jIZfKqaiJk4ZuLJDNqf5DddhgMk1sfsk8ny7NrwQZsv9psMd1A46oLakuIzOtGka30X76g+T!+x0B13yTewM23oNypg/OAbOmeb5Q0SnOGa9lu4fbIGZ8zQt54ljx5Nu6PulN/rwHpP/tcsunMnja!jj9yMco= X-Complaints-To: abuse@clear.net.nz X-DMCA-Complaints-To: abuse@clear.net.nz X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.1 Xref: archiver1.google.com comp.lang.ada:31768 Date: 2002-12-13T15:03:24+13:00 List-Id: On Wed, 11 Dec 2002 09:37:12 +0000 (UTC), Lutz Donnerhacke 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 Ada 95 mailing lists; http://www.ijs.co.nz/ada_95.htm