------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 199x by International Computer Science Institute            --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------

class TEST_RV is
   include R_TEST;

   test_rv0(rv:RENDEZVOUS_LOCK) is
      --#OUT+"rv0 started\n";
      lock when rv.r1 then
         --#OUT+"rv0 got lock\n";
      end;
   end;

   test_rv1(rv:RENDEZVOUS_LOCK):INT is
      --#OUT+"rv1 started\n";
      lock when rv.r1 then
         --#OUT+"rv1 got lock\n";
         return 1;
      end;
   end;

   test_rv2(rv:RENDEZVOUS_LOCK,b:DOOR_LOCK):INT is
      --#OUT+"rv2 started\n";
      lock 
      when rv.r2 then
         --#OUT+"rv2 got lock\n";
         return 2;
      when b.open then
         --#OUT+"rv2 got door\n";
         return 0;
      end;
   end;

   rv is
      class_name("RENDEZVOUS_LOCK");
      a::=#ATTACH;
      r::=#RENDEZVOUS_LOCK;
      lock r then
         test("locking self",true,true);
      else
         test("locking self",false,true);
      end;
      b::=#DOOR_LOCK;
      r1,r2,r3:FUTURE{INT};
      r1:=#;r2:=#;r3:=#;
      r1:-test_rv1(r);
      r2:-test_rv2(r,b);
      r3:-test_rv2(r,b);
      --#OUT+"all threads have started\n";
      test("r1",r1.get,1);
      b.open_door;
      test("r2+r3",r2.get+r3.get,2);

      g::=#ATTACH;
      nr::=#ARRAY{RENDEZVOUS_LOCK}(10);
      loop 
         i::=0.upto!(4);
         nr[i]:=#RENDEZVOUS_LOCK;
	 nr[i+5]:=nr[i]; 
      end;
      loop m::=nr.elt!;i::=nr.ind!;g:-test_rv0(m)@i%clusters; end;
      res::=#ARRAY{INT}(5);
      loop 
         lock 
	 when g.no_threads then break!;
	 when nr[0].r2 then res[0]:=res[0]+1;
	 when nr[1].r2 then res[1]:=res[1]+1;
	 when nr[2].r2 then res[2]:=res[2]+1;
	 when nr[3].r2 then res[3]:=res[3]+1;
	 when nr[4].r2 then res[4]:=res[4]+1;
	 end;
      end;
      -- res[0]=res[1]=res[2]=res[3]=res[4]=2
      test("multiple",res.str,"{2,2,2,2,2}");
      finish;
   end;

   test_rvt0(rv:RENDEZVOUS_LOCK{INT},g:GATE{INT},i:INT) is
      lock when rv.r1(i) then
	 g.enqueue(rv.get);
         g.enqueue(i);
      end;
   end;

   test_rvt1(rv:RENDEZVOUS_LOCK{INT}):INT is
      lock when rv.r1(4) then
         return rv.get;
      end;
   end;

   test_rvt2(rv:RENDEZVOUS_LOCK{INT},b:DOOR_LOCK):INT is
      lock 
      when rv.r2(9) then
         return rv.get;
      when b.open then
         return 0;
      end;
   end;

   rvt is
      class_name("RENDEZVOUS_LOCK{INT}");
      a::=#ATTACH;
      r::=#RENDEZVOUS_LOCK{INT};
      lock r then
         test("locking self",true,true);
      else
         test("locking self",false,true);
      end;
      b::=#DOOR_LOCK;
      r1,r2,r3:FUTURE{INT};
      r1:=#;r2:=#;r3:=#;
      r1:-test_rvt1(r);
      r2:-test_rvt2(r,b);
      r3:-test_rvt2(r,b);
      test("r1",r1.get,9);
      b.open_door;
      test("r2+r3",r2.get+r3.get,4);

      g::=#ATTACH;
      gt::=#GATE{INT};
      nr::=#ARRAY{RENDEZVOUS_LOCK{INT}}(10);
      loop 
         i::=0.upto!(4);
         nr[i]:=#RENDEZVOUS_LOCK{INT};
	 nr[i+5]:=nr[i]; 
      end;
      loop m::=nr.elt!;i::=nr.ind!;g:-test_rvt0(m,gt,i%5)@i%clusters; end;
      res::=#ARRAY{INT}(5);
      loop 
	 i::=10.up!;
	 j::=-1;
         lock 
	 when g.no_threads then break!;
	 when nr[0].r2(i) then res[0]:=res[0]+1;j:=0;
	 when nr[1].r2(i) then res[1]:=res[1]+1;j:=1;
	 when nr[2].r2(i) then res[2]:=res[2]+1;j:=2;
	 when nr[3].r2(i) then res[3]:=res[3]+1;j:=3;
	 when nr[4].r2(i) then res[4]:=res[4]+1;j:=4;
	 end;
         --#OUT+"doing test\n";
	 test("get",nr[j].get,j);
	 test("remote_get",gt.dequeue,i);
	 test("from",gt.dequeue,j);
      end;
      -- res[0]=res[1]=res[2]=res[3]=res[4]=2
      test("multiple",res.str,"{2,2,2,2,2}");
      finish;
   end;

   main is
      rv;
      rvt;
   end;
    
end; -- class RV_TEST

-------------------------------------------------------------------
