------------------------->  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 ZONE < $HASH is
   -- A primitive class supported by the compiler and runtimes.
   -- Zones represent a collection of objects, threads and other
   -- zones.  They are bound to particular hardware entities at
   -- runtime.
   --
   -- The basic use of zones is "expr @ zone", which causes the
   -- expression to be evaluated in the zone.  It is a runtime
   -- error for the rhs of an `@' to evaluate to `void'.  `@'
   -- can also be used with the `fork' and `parloop' statements.
   --
   -- There are three other builtin expressions useful with zones.
   -- `here' is the zone of execution of the evaluating thread.
   -- `where($OB)' is the zone of residence of its argument.
   -- `global' is a zone constant representing the entire system, the
   -- root of the hardware zone tree.  In `main', `here' starts as
   -- `global'.  This is also the value that `where' returns for void
   -- and value types.

   create:ZONE is
      -- Make a new zone; the new zone is inside the current zone.
      -- This means that objects or threads in the new zone will be
      -- inside the current zone as well.  When threads are forked,
      -- a new zone inside the current one is implicitly created.

      builtin ZONE_CREATE;
   end;

   within(arg:ZONE):BOOL is 
      -- Test whether `self' is inside of `arg'.  Transitive.  Also
      -- true if `self' and `arg' are the same zone.  If either are
      -- void, returns false.
      --
      -- Calling `SYS::destroy' on a zone recursively destroys all
      -- objects and zones inside of it.  It's a fatal error if there
      -- are any executing threads: eg. `SYS::destroy(global)'
      -- is a bad idea.

      builtin ZONE_WITHIN;
   end;

   divisions:INT is
      -- If this zone is fixed to a particular hardware entity that
      -- has meaningful subdivisions, this returns the number of
      -- divisions.
      --
      -- For example, on an SMP with 4 processors, 
      --
      --   global.divisions
      --
      -- returns 4.  On a network of workstations with 16 nodes each
      -- with two processors,
      --
      --   global.divisions
      --
      -- returns 16, while
      --
      --   global.division(0).divisions
      --
      -- returns 2.  Systems which may have a varying number of divisions
      -- (i.e. fault-tolerant networks) or for which there is no clear
      -- notion of a division (individual processors) return 0.  The number
      -- of divisions of a particular zone may not change dynamically.

      builtin ZONE_DIVISIONS;
   end;

   division(n:INT):ZONE pre n>=0 and n<divisions is
      -- Returns the `n'th division as described in `divisions'.
      -- The returned zone is inside `self'.  All zones support
      -- at least a single division; if `self' is not bound to
      -- a hardware entity, this division is legal but only symbolic.
      -- This call is not legal if divisions=0.

      builtin ZONE_DIVISION;
   end;

   divisions!:ZONE is
      -- Return the divisions in order.

      loop yield division(divisions.times!) end
   end;

   capacity:INT is
      -- The recommended thread capacity of this hardware zone.
      -- For example, on a network with three workstations each
      -- with four processors the gloabl zone would have a capacity
      -- of 12 while the zone for each workstations would have a
      -- capacity of 4.

      builtin ZONE_CAPACITY;
   end;

   is_eq(arg:$OB):BOOL is
      -- True iff `arg' is same as `self'.  If either are void, returns
      -- false.
      return ~void(self) and ~void(arg) and SYS::is_eq(self,arg);
   end;

   is_lt(arg:$OB):BOOL is
      -- An arbitrary total order for comparing zones (useful for
      -- containers).  The partial order defined by `within' is
      -- unrelated.
      return SYS::is_lt(self,arg);
   end;

   hash:INT is
      -- Hash function for zones, useful for containers.
      return SYS::hash(self);
   end;

end;

partial class ZONE_EXPR is
   -- A convenience class.

   divisions:INT is return here.divisions end;
   division(n:INT):ZONE is return here.division(n) end;
   divisions!:ZONE is loop yield here.divisions! end end;
   capacity:INT is return here.capacity end;

end;
