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,FREEMAIL_FROM autolearn=unavailable autolearn_force=no version=3.4.4 X-Received: by 10.107.8.26 with SMTP id 26mr3236518ioi.27.1513105722899; Tue, 12 Dec 2017 11:08:42 -0800 (PST) X-Received: by 10.157.51.145 with SMTP id u17mr205535otc.7.1513105722700; Tue, 12 Dec 2017 11:08:42 -0800 (PST) Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!feeder.eternal-september.org!news.kjsl.com!usenet.stanford.edu!193no2234335itr.0!news-out.google.com!s63ni71itb.0!nntp.google.com!193no2234333itr.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 12 Dec 2017 11:08:42 -0800 (PST) Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=81.67.149.115; posting-account=O_NgcgoAAABs6pgCjroQBmOBL5ZZGPUc NNTP-Posting-Host: 81.67.149.115 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: Subject: weird block on Get from basic protected bounded buffer with 2 tasks From: George Shapovalov Injection-Date: Tue, 12 Dec 2017 19:08:42 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Xref: reader02.eternal-september.org comp.lang.ada:49453 Date: 2017-12-12T11:08:42-08:00 List-Id: Hi guys, Sorry if this is a trivial issue, but I can't seem to find any (RM) rules r= egulating this or mentions of similar issues on Google.. This is a very basic protected bounded buffer in Ada, pretty much the text-= book example. (This is a part of a bigger thing, but I simplified code down= to bare minimum, where it reproduced the behavior). Don't mind the modular= type for counters please, I tried using a range (just as in GNAT.Bounded_b= uffer) or going without Counter. The indices are not a culprit here, all wa= ys to count them behave identically.. It seems to work just fine if I have 1 task feeding it and the "main" body = is reading from it. But it blocks on the 1st Get if I use 2 tasks - Putter = and Getter, just as below. with Ada.Text_IO;use Ada.Text_IO; procedure test_buffer is maxItems : constant :=3D 10; type Index is mod maxItems; maxCount : constant Index :=3D Index(maxItems - 1); type ItemArray is array(Index) of Integer; protected Buffer is entry Put(X : in Integer); entry Get(X : out Integer); private First, Last, Count : Index :=3D 0; buf : ItemArray; end; protected body Buffer is entry Put(X : in Integer) when Count < maxCount and Buffer.Get'Cou= nt =3D 0 is begin Put_Line("Put X=3D"&X'Img & "; First=3D"&First'Img&", Last=3D"&= Last'Img&", Count=3D"&Count'Img); buf(Last) :=3D X; Last :=3D Last + 1; Count :=3D Count + 1; end; -- entry Get(X : out Integer) when Count > 0 is begin X :=3D buf(First); First :=3D First + 1; Count :=3D Count - 1; Put_Line("Get X=3D"&X'Img & "; First=3D"&First'Img&", Last=3D"&= Last'Img&", Count=3D"&Count'Img); end; end; task Putter; task body Putter is begin Put_Line("Putter started"); for i in 0 ..25 loop Put_Line("putting i=3D"&i'Img); Buffer.Put(i); end loop; end; task Getter; task body Getter is X : Integer; begin Put_Line("Getter started"); loop Put_Line("getting X.."); Buffer.Get(X); Put_Line(", got X=3D"&X'Img); end loop; end; -- X : Integer; begin -- loop -- Buffer.Get(X); -- Put_Line("got X=3D"&X'Img); -- end loop; abort Getter; end test_buffer; The output it gives me looks like this: $ ./test_buffer=20 Getter started getting X.. Putter started Put X=3D 0; First=3D 0, Last=3D 0, Count=3D 0 Put X=3D 1; First=3D 0, Last=3D 1, Count=3D 1 Put X=3D 2; First=3D 0, Last=3D 2, Count=3D 2 Put X=3D 3; First=3D 0, Last=3D 3, Count=3D 3 Put X=3D 4; First=3D 0, Last=3D 4, Count=3D 4 Put X=3D 5; First=3D 0, Last=3D 5, Count=3D 5 Put X=3D 6; First=3D 0, Last=3D 6, Count=3D 6 Put X=3D 7; First=3D 0, Last=3D 7, Count=3D 7 Put X=3D 8; First=3D 0, Last=3D 8, Count=3D 8 ^C Sometimes it manages to read one or two items before blocking (thenn more a= re pushed in correspondingly): $ ./test_buffer=20 Putter started Put X=3D 0; First=3D 0, Last=3D 0, Count=3D 0 Put X=3D 1; First=3D 0, Last=3D 1, Count=3D 1 Put X=3D 2; First=3D 0, Last=3D 2, Count=3D 2 Put X=3D 3; First=3D 0, Last=3D 3, Count=3D 3 Put X=3D 4; First=3D 0, Last=3D 4, Count=3D 4 Put X=3D 5; First=3D 0, Last=3D 5, Count=3D 5 Put X=3D 6; First=3D 0, Last=3D 6, Count=3D 6 Getter started getting X.. Put X=3D 7; First=3D 0, Last=3D 7, Count=3D 7 Put X=3D 8; First=3D 0, Last=3D 8, Count=3D 8 Get X=3D 0; First=3D 1, Last=3D 9, Count=3D 8 , got X=3D 0 getting X.. Get X=3D 1; First=3D 2, Last=3D 9, Count=3D 7 , got X=3D 1 getting X.. Put X=3D 9; First=3D 2, Last=3D 9, Count=3D 7 Put X=3D 10; First=3D 2, Last=3D 0, Count=3D 8 Get X=3D 2; First=3D 3, Last=3D 1, Count=3D 8 Put X=3D 11; First=3D 3, Last=3D 1, Count=3D 8 ^C I was suspecting issues with the barrier (thus that 'Count check in there j= ust for the heck of it - I thought might be prioritizing Gets would make it= behave, but its exactly the same without using 'Count in when). However I = cannot seem to find any rule that would stall the barrier on Get (2nd task = is external to the protected object, so no, its not the no reevaluation on = internal calls of protected object). Oh, and if I move comments around, to = execute Gets in the loop in the main part (whether I comment out or leave G= etter running in parallel), then it seems to work Ok.. So, what gives? Am I missing something here or is this a bug? The used platform: Gentoo Linux, gnat-gpl-2017, gcc-6.3.0