{ *************************************************************************** }
MODULE mod_io_allocation_handling ;
{  Created   9-MAR-1990  MICHIGAN STATE UNIVERSITY, TRIGGER CONTROL SOFTWARE }
{ *************************************************************************** }
INCLUDE 
  mod_handle_tracing,
  mod_common_hard_io ;
{ *************************************************************************** }
EXPORT 
  allocate_trigger,             {PROCEDURE signal begining of exclusive use   }
  deallocate_trigger ;          {PROCEDURE return to shared resource          }
{ *************************************************************************** }
IMPORT
  handle_trc_sys,                     {from module MOD_HANDLE_TRACING         }

  trg_alloc ;                   {from module MOD_COMMON_HARD_IO               }
{ *************************************************************************** }
PROCEDURE allocate_trigger ( caller_id :^ANYTYPE ; 
                                report : BOOLEAN := TRUE ;
                                tagext : VARYING_STRING(16) := '' ) ;
{**** one MUST pass in caller_id the ^cbus_param_list that will be used for IO}
BEGIN

  IF ( report = TRUE ) 
  THEN handle_trc_sys ( TAG := 'ALL/TIO%'+tagext,  
                    MESSAGE := ' Allocating Trigger IO' ) ;

  IF ( trg_alloc.allocated <> TRUE )  

  THEN BEGIN                            {trigger up for grabs                 }
    CLEAR_EVENT ( trg_alloc.released ); {clear previous deallocation flag     }
    trg_alloc.owner := caller_id ;      {mark trigger with process' id        }
    trg_alloc.allocated := TRUE ;       {mark trigger as allocated            }
    trg_alloc.active    := FALSE ;      {mark owner not doing io              }
  END 

  ELSE BEGIN
    IF ( caller_id <> trg_alloc.owner ) 
    THEN BEGIN                        {if caller was not already owner      }
      WAIT_ANY ( trg_alloc.released );{wait for owner to release the trigger}
      allocate_trigger ( caller_id ) ;{recursive allocation request         }
    END ;
  END ;

END ;
{ *************************************************************************** }
{ *************************************************************************** }
PROCEDURE deallocate_trigger ( report : BOOLEAN := TRUE ;
                               tagext : VARYING_STRING(16) := '' ) ;
BEGIN

  IF ( report = TRUE ) 
  THEN IF ( trg_alloc.owner <> NIL )                        {it was allocated }
  THEN handle_trc_sys ( TAG := 'ALL/TIO%'+tagext,  
                    MESSAGE := ' Deallocating Trigger IO' ) ;

  { wait for owner to be done with current IO cycle before deallocating }
  WHILE ( trg_alloc.active = TRUE ) DO WAIT_ANY ( TIME := -1000 ) ;
  
  trg_alloc.allocated := FALSE ;                   {deallocate in either case }
  trg_alloc.owner := NIL ;    
  SIGNAL ( trg_alloc.released ) ;  

END ;
{ *************************************************************************** }
END .
