------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- 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>  <--------------

abstract class $LOCK_MGR is

--        This abstract class, at the 'root' of the lock manager hierarchy
--   models the object which manages locks used by some other object or objects
--   (such as threads, zones, etc.).

--         Version 1.0 Nov 98.   Copyright K Hopper, U of Waikato

--                          Development History
--                          -------------------

--        Date           Who By         Detail
--        ----           ------         ------

--       15 Nov 98        kh       Original from 1.2 distrib.

try : BOOL ;

--        This routine returns true if and only if it has been possible to lock
--   self.


lck ;

--        This routine returns locks self, waiting if necessary.


release ;

--        This routine releases/unlocks self.


is_locked : BOOL ;

--        This predicate returns true if and only if self is locked.


taken_over : BOOL ;

--        This is the reader routine which returns true if and only if this
--   lock has been taken over by another.


taken_over(
           to : BOOL
           ) ;

--        This routine is the corresponding writer routine - establishing that
--   self has been taken over by another manager.


controls(
         these_locks : REFERENCE,
         size : CARD
         ) : BOOL ;

--        This predicate returns true if and only if all of the locks indicated
--   by the first argument (an array of size elements) are all controlled by
--   self.


managed_locks : ARRAY{$LOCK} ;

--        This feature is a list of all of the locks managed by self.


managed_queues : ARRAY{THREAD_HANDLE_QUEUE} ;

--        This feature is a list of all of the queues waiting on the respective
--   managed locks.


number_of_threads_holding_locks : CARD ;

--        This feature gives the number of threads holding one or more locks
--   managed by self.


acquire_single_lock(
                    lck : $LOCK
                    ) ;

--        This routine acquires the given lock (which must be one of those
--   managed by this manager)  on behalf of the calling thread.


try_single_lock(
                lck : $LOCK
                ) :  CARD ;

--        This routine tries to obtain the indicated lock (which must be one of
--   those managed by this manager) on behalf of the calling thread, returning
--   true zero if and only if the lock has been obtained.


release_single_lock(
                    lck : $LOCK
                    ) ;

--        This routine releases the given lock if it is managed by this manager.


unlock_single_lock(
                   lck : $LOCK
                   ) ;

--        This routine is a synonym of release.

end ; -- $LOCK_MGR

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

abstract class $LOCK_MGR_ACCESS is

--        This abstraction models the access control object of the lock manager
--   is specified.

--         Version 1.0 Nov 98.   Copyright K Hopper,U of Waikato

--                          Development History
--                          -------------------

--        Date           Who By         Detail
--        ----           ------         ------

--       15 Nov 98        kh       Original from 1.2 distrib.


manager : $LOCK_MGR ;

--        This feature returns the identity of the local manager of self.


get_manager : $LOCK_MGR ;

--        This routine returns the actual lock manager identity for self,
--   whatever cluster it may be on.


try_manager : $LOCK_MGR ;

--        This routine attempte to lock the manager of self whatever platform
--   it is on, returning true if and only if the lock has successfully been
--   obtained.


set_manager(
            lock_mgr : $LOCK_MGR
            ) ;

--        This routine sets the manager of self to be the one passed as
--   argument.


init_queue ;

--        This routine initialises the manager queue structure.


queue : THREAD_HANDLE_QUEUE ;

--        This routine returns the queue of threads waiting on self.


set_queue(
          queue : THREAD_HANDLE_QUEUE
          ) ;

--        This routine swets the queue of threads to be the argument passed.


local_queue : THREAD_HANDLE_QUEUE ;

--        This routine returns the local queue of threads for self.


access_acquire_single_lock ;

--        This routine obtains the access lock for the manager of self, waiting
--   if necessary.


access_try_single_lock : CARD ;

--        This routine attempts to obtain the access lock for the manager of
--   self, returning the lock index in the array of locks.


access_release_single_lock ;

--        This routine releases the access lock for the manager of self.


access_acquire_double_lock(
                           this_lock : QMUTEX
                           ) ;

--        This routine obtains both the access lock for the manager of self and
--   the lock passed as argument, waiting if necessary.


access_try_double_lock(
                       this_lock : QMUTEX
                       ) : CARD ;

--        This routine attempts to obtain both the access lock for the manager
--   of self and the lock passed as argument, returning non-zero if and only if
--   both locks have been successfully acquired.


access_release_double_lock(
                           this_lock : QMUTEX
                           ) ;

--        This routine frees both the access lock for the manager of self and
--   the lock passed as argument.


access_acquire_conjunctive_locks(
                                  these_locks : REFERENCE,
                                  number : CARD
                                  ) ;

--        This routine obtains all of the locks in the array of locks given as
--   the first argument, waiting if necessary.


access_try_conjunctive_locks(
                              these_locks : REFERENCE,
                              number  : CARD
                              )  : CARD ;

--        This routine tries to obtain all of the locks in the array of locks
--   given as the first argument, returning non-zero if and only if all locks are
--   held.


access_release_conjunctive_locks(
                                 these_locks : REFERENCE,
                                 number : CARD
                                 ) ;

--        This routine releases all of the locks in the array of locks given as
--   the first argument.


access_acquire_disjunctive_locks(
                                  stmt : REFERENCE
                                  ) : CARD ;

--        This routine returns the index into the statement when clauses which
--   corresponds to the first lock group locked (searching from the
--   beginning).  If there is an else clause and no group is locked then zero
--   is returned otherwise the routine waits.


access_try_disjunctive_locks(
                             stmt : REFERENCE
                             ) : CARD ;

--        This routine returns the index into the statement when clauses which
--   corresponds to the first lock group locked (searching from the
--   beginning).  If there is an else clause and no group is locked then zero
--   is returned otherwise CARD::maxval is returned.

end ; -- $LOCK_MGR_ACCESS

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

abstract class $SINGLE_LOCK_MGR < $LOCK_MGR is

--        This class models the single lock manager - which is, of course,
--   the identical model to the $LOCK_MGR above!

--         Version 1.0 Nov 98.   Copyright K Hopper, U of Waikato

--                          Development History
--                          -------------------

--        Date           Who By         Detail
--        ----           ------         ------

--       15 Nov 98        kh       Original from 1.2 distrib.

end ; -- $SINGLE_LOCK_MGR

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

abstract class $COMBINED_LOCKS_MGR < $LOCK_MGR is

--        This abstraction models the notions of both conjunctive and
--   disjunctive lock management.

--         Version 1.0 Nov 98.   Copyright K Hopper, U of Waikato

--                          Development History
--                          -------------------

--        Date           Who By         Detail
--        ----           ------         ------

--       15 Nov 98        kh       Original from 1.2 distrib.


acquire_conjunctive_locks(
                          these_locks : REFERENCE,
                          number : CARD
                          ) ;

--        This routine acquires all of the locks indicated by the first
--   argument (which is an implementation-defined array of number elements).


try_conjunctive_locks(
                      these_locks : REFERENCE,
                      number : CARD
                      ) : CARD ;

--        This routine attempts to acquire all of the locks indicated by the
--   first argument (which is an implementation-defined array of number
--   elements).  Non-zero is returned if and only if this has been successful
--   and the locks are all held.


release_conjunctive_locks(
                          these_locks : REFERENCE,
                          number : CARD
                          ) ;

--        This routine releases all of the locks indicated by the first
--   argument (which is an implementation-defined array of number elements).


acquire_disjunctive_locks(
                          these_locks : REFERENCE,
                          max_size : CARD,
                          clauses : CARD
                          ) : CARD ;

--        This routine returns the first index into the 'when clauses' of the
--   lock groups indicated by the first argument which corresponds to the locks
--   held.  If no locks are held and there is an else clause (the element at
--   index zero is not void) then zero is returned, else the routine waits
--   until a lock (group) has been obtained.


try_disjunctive_locks(
                      these_locks : REFERENCE,
                      max_size : CARD,
                      clauses : CARD
                      ) : CARD ;

--        This routine returns the first index into the 'when clauses' of the
--   lock groups indicated by the first argument which corresponds to the locks
--   held.  If no locks are held and there is an else clause (the element at
--   index zero is not void) then zero is returned, else CARD::maxval.

end ; -- $COMBINED_LOCKS_MGR

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

partial class LOCK_STUBS_INCL is

--        This partial class merely collects together all of ths stubs needed
--   for a lock manager implementation.

--         Version 1.0 Nov 98.   Copyright K Hopper,U of Waikato

--                          Development History
--                          -------------------

--        Date           Who By         Detail
--        ----           ------         ------

--       15 Nov 98        kh       Original from 1.2 distrib.


stub acquirable(
                 tid : THREAD_ID
                 ) : BOOL ;

--        This predicate returns true if and only if the lock is either free
--   or locked by the given thread.


stub acquire(
             tid : THREAD_ID
             ) ;

--        This routine increments the lock count ans sets the identity of
--   the locker to be the given parameter.


stub release(
             tid : THREAD_ID
             ) ;

--        This routine decrements the lock count ans if it is then zero unsets
--   the locker thread to be nil.


stub request(
             tid : THREAD_ID
             ) ;

--        This routine requests the lock for the given thread - which may
--   involve waiting.


stub cancel_request(
                    tid : THREAD_ID
                    ) ;

--        This routine cancels the request for the lock made by the given
--   thread.


stub wait_for(
              tid : THREAD_ID
              ) ;

--        This routine blocks if this thread has an outstanding request for
--   the lock.


stub waiting_for(
                 tid : THREAD_ID
                 ) : ARRAY{THREAD_ID} ;

--        This routine returns the identity of the threads which are locking
--   this lock -- provided that it is not the one specified in the argument.


stub combinations : ARRAY{ARRAY{$LOCK}} ;

--        This routine returns an array of arrays of lock which indicates
--   the invoking lock in the first element and the helpers in the second.


stub combined_with(
                    lcks : ARRAY{$LOCK},
                    tids : ARRAY{THREAD_ID}
                    ) ;

--        This routine associates a thread with a lock for each of the pairs
--   provided as arguments.


stub my_manager : $LOCK_MGR ;

--        This feature returns the lock manager.


stub my_queue : THREAD_HANDLE_QUEUE ;

--        This feature is the queue of threads waiting on self.


stub my_local_queue : THREAD_HANDLE_QUEUE ;

--        This feature is the queue of local threads waiting on self.


stub manager : $LOCK_MGR ;

--        This routine returns the lock manager in use by self.


stub set_manager(
                 lock_mgr : $LOCK_MGR
                 ) ;

--        This routine sets the manager in use by self to be the lock manager
--   provided as argument.


stub get_manager : $LOCK_MGR ;

--        This routine repeatedly attempts to lock its lock manager until the
--   correct one is obtained in the presence of possible changing of the
--   manager by other threads.


stub try_manager : $LOCK_MGR ;

--        This routine attempts to lock the manager itself, returning the
--   manager if successful.


stub init_queue ;

--        This routine initialises the internal thread queue.


stub queue : THREAD_HANDLE_QUEUE ;

--        This feature is the queue of all threads waiting for self.


stub set_queue(
               queue : THREAD_HANDLE_QUEUE
               ) ;

--        This routine establishes the argument as the queue of waiting threads.


stub local_queue : THREAD_HANDLE_QUEUE ;

--        This feature is the local queue of threads waiting.


stub access_acquire_single_lock ;

--        This routine acquires self.


stub access_try_single_lock : CARD ;

--        This routine attempts to acquire self, returning non-zero if and only if
--   successful.


stub access_release_single_lock ;

--        This routine releases self.


stub access_acquire_double_lock(
                                this_lock : $LOCK
                                ) ;

--        This routine acquires both the argument lock and self.


stub access_try_double_lock(
                            this_lock : $LOCK
                            ) : CARD ;

--        This routine attempts to obtain both self and the given lock,
--   returning non-zero if and only if both have been successfully obtained.


stub access_release_double_lock(
                                this_lock : $LOCK
                                ) ;

--        This routine releases both self and the given lock.


stub access_acquire_conjunctive_locks(
                                      these_locks : REFERENCE,
                                      number : CARD
                                      ) ;

--        This routine acquires the group of locks indicated byt the first
--   argument, which is a reference to an array of locks of the given size.


stub access_try_conjunctive_locks(
                                  these_locks : REFERENCE,
                                  number : CARD
                                  ) : CARD ;

--        This routine attempts to obtain the group of locks indicated by the
--   first argument, returning non-zero if and only if all locks have been
--   successfully obtained.


stub access_release_conjunctive_locks(
                                      these_locks : REFERENCE,
                                      number : CARD
                                      ) ;

--        This routine releases all of the locks indicated by the first
--   argument.


stub access_acquire_disjunctive_locks(
                                      stmt : REFERENCE
                                      ) : CARD ;

--        This routine determines which of the when clauses in the given
--   statement has been locked, returning the index found.  If no lock is
--   locked and there is no else clause then zero is returned, otherwise this
--   waits for a lock group to be locked.


stub access_try_disjunctive_locks(
                                  stmt : REFERENCE
                                  ) : CARD ;

--        This routine determines which of the when clauses in the given
--   statement has been locked, returning the index found.  If no lock is
--   locked and there is no else clause then zero is returned, otherwise
--   returning CARD::maxval.

end ; -- LOCK_STUBS_INCL

