



		    proc_int_handler.pl1            11/11/89  1106.6rew 11/11/89  0806.8       66321



/****^  ***********************************************************
        *                                                         *
        * Copyright, (C) Honeywell Bull Inc., 1987                *
        *                                                         *
        * Copyright, (C) Honeywell Information Systems Inc., 1984 *
        *                                                         *
        * Copyright (c) 1972 by Massachusetts Institute of        *
        * Technology and Honeywell Information Systems, Inc.      *
        *                                                         *
        *********************************************************** */



/****^  HISTORY COMMENTS:
  1) change(85-11-27,Herbst), approve(87-07-20,MCR7697),
     audit(87-07-20,GDixon), install(87-08-04,MR12.1-1055):
     Added system_message_sct_index.
                                                   END HISTORY COMMENTS */


/* format: style2,indcomtxt */

/* DESCRIPTION:
   Process Interrupts Are Sent Here.
*/

/* HISTORY:
Written by N. I. Morris, 09/14/71.
Modified:
10/02/72 by N. I. Morris:  for 6090.
12/04/75 by D. M. Wells:  to add neti condition.
02/12/76 by Noel I. Morris:  for new connect mechanism.
07/01/77 by T. Casey:  to add susp and term.
01/12/79 by C. Hornig:  to add wkp_.
12/03/83 by BIM:  for pgt_.
07/16/84 by R. Michael Tague:  Added dm_shutdown_warning_ and dm_user_shutdown_
08/22/84 by R. Michael Tague:  Removed dm_shutdown_warning_ and
            dm_user_shutdown_.  Added system_shutdown_scheduled_ and
            dm_shutdown_scheduled_.
*/

proc_int_handler:
     procedure;

	dcl     msg		 bit (36) aligned,	/* IPS message after masking */
	        stacq_temp		 bit (36) aligned,
	        new_ips_message	 bit (36) aligned,
	        mc_ptr		 ptr,		/* pointer to machine conditions */
	        fim_code		 fixed bin (17),	/* code to index into SCT */
	        i			 fixed bin,	/* index into mask data table */
	        ringno		 fixed bin (3),	/* ring number */
	        r			 fixed bin (3),	/* ring number iteration variable */
	        name		 char (31);	/* condition name from table */

	dcl     (
	        pds$apt_ptr		 ptr,		/* pointer to APT entry for this process */
	        pds$ips_mask	 (0:7) bit (36),	/* IPS masks for this process */
	        pds$auto_mask	 (0:7) bit (36),	/* automatic IPS masks for this process */
	        pds$signal_data	 (32) fixed bin
	        )			 ext;		/* machine conditions for signalling */

	dcl     1 pds$condition_name	 external,
	        ( 2 lth		 fixed bin (9) unsigned,
		2 name		 char (31)
		)		 unal;

	dcl     pds$process_group_id	 char (32) ext static;

	dcl     (addr, bit, fixed, length, rtrim, stacq, substr)
				 builtin;

	dcl     signaller		 ext entry;
	dcl     ring_alarm$set	 ext entry (fixed bin (3));
	dcl     syserr		 entry options (variable);


/* Get pointers to machine conditions and extract information. */

	mc_ptr = addr (pds$signal_data);		/* Machine conditions have been put here for us. */
	scup = addr (mc_ptr -> mc.scu);		/* Generate a pointer to SCU info. */
	ringno = fixed (scup -> scu.ppr.prr, 3);	/* Extract ring number from machine conditions. */
	aptep = pds$apt_ptr;			/* Get a pointer to APT entry for this process. */


/* See if any of the events set in the APT entry ips_message are unmasked
   in this ring or any higher ring.  If not, just return;			*/

	do r = ringno to 7;				/* Start checking in this ring. */
	     msg = apte.ips_message & pds$ips_mask (r);	/* Are we taking this signal in this ring? */
	     if msg
	     then do;				/* If so ... */
		     do i = 1 to sys_info$ips_mask_data.count;
						/* Search for bit. */
			if msg & sys_info$ips_mask_data.mask (i).mask
			then goto found_ips;	/* If found, go process it. */
		     end;
		     /*** got an invalid bit */
		     call syserr (LOG, "proc_int_handler: Invalid IPS interrupt(s) ^w for ^a.", msg,
			pds$process_group_id);
		     stacq_temp = apte.ips_message;
		     new_ips_message = stacq_temp & sys_info$all_valid_ips_mask;
		     do while (^stacq (apte.ips_message, new_ips_message, stacq_temp));
			stacq_temp = apte.ips_message;
			new_ips_message = stacq_temp & sys_info$all_valid_ips_mask;
		     end;
		     return;			/* Ignore unmeaningful messages. */
		end;
	end;
	return;					/* Message not unmasked in any ring. */


/* The message was found in some ring.  If the ring is higher than
   current ring, set ring alarm to catch exit to that ring.		*/

found_ips:
	if r > ringno
	then do;					/* If unmasked in a higher ring ... */
		call ring_alarm$set (r);		/* Set a ring alarm to go off later. */
		return;				/* Return to caller. */
	     end;


/* The message was found in this ring.  Remove appropriate bit
   from APT entry ips_message, and check for automatic masking.
   If automatic masking is indicated, mask _a_l_l IPS events after
   saving the current mask in the machine conditions.		*/

	msg = sys_info$ips_mask_data.mask (i).mask;	/* Get only the correct bit. */
	stacq_temp = apte.ips_message;
	new_ips_message = stacq_temp & ^msg;
	do while (^stacq (apte.ips_message, new_ips_message, stacq_temp));
	     stacq_temp = apte.ips_message;
	     new_ips_message = stacq_temp & ^msg;
	end;

	if msg & pds$auto_mask (ringno)
	then do;					/* If automatic masking to take place ... */
		mc_ptr -> mc.ips_temp = pds$ips_mask (ringno) | "000000000000000000000000000000000001"b;
						/* Save the mask with low-order bit on. */
		pds$ips_mask (ringno) = "0"b;		/* Now mask everything. */
	     end;
	else /* If not automatic masking ... */
	     mc_ptr -> mc.ips_temp = "0"b;		/* Clear the IPS mask in machine conditions. */


/* Copy the condition name and the machine conditions in PDS
   in preparation for signalling.  Finally, call the signaller
   to signal this event.					*/

	name = substr(sys_info$ips_mask_data.mask (i).name,1,length(name));
						/* Grab the name. */
	pds$condition_name.lth = length (rtrim (name));	/* Determine the length of the name. */
	pds$condition_name.name = name;		/* Set the condition name. */

	if i = 1
	then fim_code = quit_sct_index;
	else if i = 2
	then fim_code = cput_sct_index;
	else if i = 3
	then fim_code = alrm_sct_index;
	else if i = 4
	then fim_code = neti_sct_index;
	else if i = 5
	then fim_code = susp_sct_index;
	else if i = 6
	then fim_code = term_sct_index;
	else if i = 7
	then fim_code = wkp_sct_index;
	else if i = 8
	then fim_code = pgt_sct_index;
	else if i = 9
	then fim_code = system_shutdown_scheduled_sct_index;
	else if i = 10
	then fim_code = dm_shutdown_scheduled_sct_index;
	else if i = 11
	then fim_code = system_message_sct_index;
	else fim_code = 0;
	mc_ptr -> mc.fcode = bit (fim_code, 17);	/* place code in MC for outer-ring use */

	call signaller;				/* Transfer control to the signaller. */

/* format: off */
%page; %skip (4); %include mc;
%page; %skip (4); %include static_handlers;
%page; %skip (4); %include apte;
%page; %skip (4); %include ips_mask_data;
%page; %skip (4); %include syserr_constants;

/* BEGIN MESSAGE DOCUMENTATION

   Message:
   proc_int_handler: Invalid IPS interrupt(s) IPS_BITS for USERNAME.

   S:     $info

   T:     $run

   M:     One or more undefined IPS messages as indicated by IPS_BITS
   have been sent to user USERNAME. They are ignored.

   A:     $contact


   END MESSAGE DOCUMENTATION */

     end proc_int_handler;




		    ring_alarm.pl1                  11/11/89  1106.6r w 11/11/89  0813.0      101367



/****^  ******************************************************
        *                                                    *
        * Copyright, (C) Honeywell Bull Inc., 1987           *
        *                                                    *
        * Copyright (c) 1986 by Massachusetts Institute of   *
        * Technology and Honeywell Information Systems, Inc. *
        *                                                    *
        * Copyright (c) 1972 by Massachusetts Institute of   *
        * Technology and Honeywell Information Systems, Inc. *
        *                                                    *
        ****************************************************** */



/****^  HISTORY COMMENTS:
  1) change(86-05-13,GJohnson), approve(86-05-13,MCR7387),
     audit(86-05-13,Martinson), install(86-05-14,MR12.0-1056):
     Correct error message documentation.
                                                   END HISTORY COMMENTS */


/* format: style2 */

/* RING_ALARM - The Ring Alarm Register Management Procedure.
	coded 10/2/72 by S. H. Webber and N. I. Morris		
	modified 2/26/76 by Noel I. Morris for new reconfig 
	modified 2/8/82 by J. Bongiovanni to set ralr to 1 if masked (conditionally) 

          modified 830518 BIM to correctly check pds */
/*        futher modified 8306 to revamp strategy -- call side polling added */

/* 830529 BIM to add poll entrypoint for call side ring alarm check */
/* Modified 1985-01-21, BIM: admin_privilege resetting. */

/* See level.alm for explanation of validation level protocols. */


ring_alarm:
     procedure;


	dcl     a_mcp		 ptr;		/* pointer to machine conditions */

	dcl     target_ring		 fixed bin (3);	/* target ring which caused ring alarm fault */
	dcl     i			 fixed bin;	/* ring number iteration variable */
	dcl     mask		 fixed bin (71);	/* interrupt mask */
	dcl     setting		 fixed bin (4);	/* new setting for ring alarm register */

	dcl     pds$admin_privileges	 bit (36) aligned ext;
	dcl     pds$alarm_ring	 fixed bin (3) ext; /* setting of ring alarm register */
	dcl     pds$apt_ptr		 ptr ext;		/* pointer to APT entry for this process */
	dcl     pds$connect_pending	 bit (1) aligned ext;
						/* non-zero if fim to do connect after return */
	dcl     pds$ips_mask	 (0:7) bit (36) aligned ext;
						/* mask for IPS signals in each ring */
	dcl     pds$ring_alarm_val	 (0:7) fixed bin (3) ext;

	dcl     pds$process_group_id	 char (32) ext static;
	dcl     pds$validation_level	 fixed bin (3) ext; /* current validation level */

	dcl     scs$sys_level	 fixed bin (71) ext;

	dcl     wired_hardcore_data$trap_invalid_masked
				 bit (1) aligned ext;
	dcl     severity		 fixed bin;
	dcl     (stop_flag, pre_empt_flag, ips_flag, check_ips, validation_flag, privileges_flag)
				 bit (1) aligned init ("0"b);
						/* flags to prevent resetting alarm after detecting condition */

	dcl     fs_get$path_name	 entry (ptr, char (*), fixed bin (21), char (*), fixed bin (35));
	dcl     pmut$lrar		 entry (fixed bin (3));
	dcl     pmut$read_mask	 entry (fixed bin (71));
	dcl     pxss$force_stop	 entry;
	dcl     set_privileges$admin_ring_alarm
				 entry;
	dcl     syserr		 entry options (variable);
	dcl     syserr$binary	 entry options (variable);
	dcl     (addr, codeptr, fixed, max, min, mod)
				 builtin;

	declare active_hardcore_data$validation_fix_severity
				 fixed bin external;
	dcl     any_other		 condition;


/* RING_ALARM$FAULT - The Ring Alarm Fault Handler. */

fault:
     entry (a_mcp);
	mcp = a_mcp;				/* copy arg */

	scup = addr (mcp -> mc.scu (0));		/* get pointer to SCU data */

/* Determine the target ring at the time of the fault. */

	target_ring = fixed (scup -> scu.tpr.trr, 3);

	call ANALYZE_RING_ALARM$$fault (target_ring);


	pds$connect_pending = pds$connect_pending | stop_flag | pre_empt_flag | ips_flag;
						/* On fault side we still take connects */

/* No other checks are made now.  We will drop into the code for
   ring_alarm$reset to compute and set a new value for the
   ring alarm register.					*/


/* RING_ALARM$RESET - Compute new setting for ring alarm register. */

reset:
     entry;

Reset_common:
	pds$alarm_ring = 0;				/* we do complete calculation, so */
	setting = 8;				/* Start with ring alarm reg turned off. */

	aptep = pds$apt_ptr;			/* Get a pointer to APT entry for this process. */
	check_ips = ^ips_flag & (apte.ips_message ^= ""b);


	do i = 0 to 7 while (setting = 8);		/* Iterate through all rings. */

	     if check_ips & ((apte.ips_message & pds$ips_mask (i)) ^= ""b)
						/** if pending IPS */
	     then setting = i;
	     else if pds$ring_alarm_val (i) ^= 0	/** or validation level was set to this ring ... */
		& (i < 7)				/** cant call into 7 */
	     then setting = i + 1;			/* if we go beyond this ring */
	end;

	if (pds$admin_privileges ^= ""b)		/* Can only happen in ring 0 */
	then setting = min (2, setting);		/* target ring is 2 */

/* Test for deferred pre-empt or stop. */

	if (apte.pre_empt_pending & ^pre_empt_flag)
	then setting = 1;
	else if (apte.stop_pending & ^stop_flag)
	then setting = 1;

/* Test for interrupts masked if debug parameter is set */

	if wired_hardcore_data$trap_invalid_masked
	then do;
		call pmut$read_mask (mask);
		if mask = scs$sys_level
		then setting = 1;
	     end;


/* Now, reset the ring alarm register if necessary. */

	setting = mod (setting, 8);			/* Compute new value for RAR. */
	call set (fixed (setting, 3));		/* And call recursively to set it. */

	return;

reset_no_pre_empt:
     entry;

	pre_empt_flag = "1"b;
	go to Reset_common;


/* SET - Entry to set the ring alarm ring. */

set:
     entry (ringno);

	dcl     ringno		 fixed bin (3);	/* ring number to which to set ring alarm */


	setting = pds$alarm_ring;			/* Get current RAR setting. */
	if setting = 0
	then setting = 8;				/* Set to 8 if RAR turned off. */
	setting = min (setting, ringno);		/* Set new RAR value. */
	pds$alarm_ring = mod (setting, 8);		/* .. */
	call pmut$lrar (pds$alarm_ring);		/* Call privileged procedure to load RAR. */

	return;


/* RING_ALARM$POLL -- on call side, check for ring alarms that we can avoid. */


poll:
     entry returns (bit (1) aligned);

	declare callerframe		 pointer;
	declare outer_ring_ptr	 pointer;
	declare its_ptr		 pointer;

	if wired_hardcore_data$trap_invalid_masked
	then do;
		call pmut$read_mask (mask);
		if mask = scs$sys_level
		then call syserr (CRASH, "ring_alarm$poll: processor is masked at exit from ring 0.");
	     end;


	callerframe = stackframeptr () -> stack_frame.prev_sp -> stack_frame.prev_sp;
						/* caller of the gate that called us */

	outer_ring_ptr = callerframe -> stack_frame.return_ptr;
						/* now, the ring number of outer_ring_ptr has to be first ring number of the caller's stack or larger */

	its_ptr = addr (outer_ring_ptr);
	target_ring = its_ptr -> its_unsigned.ringno;	/* get it as fb */

	call ANALYZE_RING_ALARM (target_ring);

	if ^pre_empt_flag & ^stop_flag
	then do;					/* Was either validation level, which ANALYZE fixed, */
						/* or privileges, which ANALYZE fixed, */
						/* or IPS, which we cannot handle yet, */
						/* or completely off the wall.  */
		call reset;			/* recurse: another ring may still need an rar */
		return ("0"b);			/* returns to outer ring for the gate */
	     end;


	if stop_flag
	then call pxss$force_stop;			/* This is supposed to be easy */

/* PRE-EMPT */

	if pre_empt_flag
	then do;
		call reset_no_pre_empt;		/* in case of val level or IPS */
		return ("1"b);
	     end;

	call syserr (CRASH, "ring_alarm$poll: Mysterious ring alarm.");


/* This procedure looks at the state in the PDS, and sets bits to indicate */
/* why the ring alarm register was set.  */


ANALYZE_RING_ALARM:
     procedure (Target_ring);

	declare Target_ring		 fixed bin (3);
	declare fault		 bit (1);
	declare old_validation_level	 fixed bin (3);

	fault = "0"b;
	go to Join;

ANALYZE_RING_ALARM$$fault:
     entry (Target_ring);

	fault = "1"b;

Join:
	old_validation_level = pds$validation_level;

	do i = 0 to Target_ring - 1;			/* check all rings up to the one being returned to */
	     if pds$ring_alarm_val (i) ^= 0
	     then do;
		     pds$validation_level = pds$ring_alarm_val (i);
		     pds$ring_alarm_val (i) = 0;	/* no longer important */
		end;
	end;

	pds$validation_level = max (Target_ring, pds$validation_level);
						/* never let it be < execution ring */
						/* do this LAST, to respect saved value if possible. */

	if old_validation_level ^= pds$validation_level & active_hardcore_data$validation_fix_severity >= 0
	then do;
		call syserr (active_hardcore_data$validation_fix_severity,
		     "ring_alarm: Fixed validation level^[ on fault^] from ^d to ^d.", fault, old_validation_level,
		     pds$validation_level);
		validation_flag = "1"b;
	     end;

	if pds$admin_privileges ^= ""b & Target_ring > 1
	then do;					/* Always call syserr, since this is always a bug */
		if active_hardcore_data$validation_fix_severity = -1
		then severity = JUST_LOG;
		else severity = active_hardcore_data$validation_fix_severity;
		call syserr (severity, "ring_alarm: Reset admin privileges^[ on fault^].", fault);
		call set_privileges$admin_ring_alarm;
		privileges_flag = "1"b;
	     end;

/* Check to see if a stop interrupt has been delayed */

	aptep = pds$apt_ptr;			/* Get pointer to our APT entry. */
	if apte.stop_pending
	then stop_flag = "1"b;

/* Check to see if a pre-empt interrupt has been delayed. */

	else if apte.pre_empt_pending
	then pre_empt_flag = "1"b;

/* Now check for any delayed IPS signals */

	else if apte.ips_message & pds$ips_mask (Target_ring)
	then ips_flag = "1"b;

	return;					/* Caller can now decide what to do with this mess */

     end ANALYZE_RING_ALARM;


/* BEGIN MESSAGE DOCUMENTATION

   Message: 
   ring_alarm$poll: processor is masked at exit from ring 0.

   S:  $crash

   T:  $run

   M:  A software bug has left interrupts masked to system level at
   exit from ring 0. 

   A:  $inform


   Message:
   ring_alarm$poll: Mysterious ring alarm.

   S:  $crash

   T:  $run

   M:  The ring alarm register was set on exit from ring zero, but no reason
   for it was recorded for the process.

   A:  $inform


   Message:
   ring_alarm: Fixed validation level {on fault} from OLD to NEW.

   S:   $beep

   T:   $run

   M:   On exit from ring zero, the validation level was less than the ring 
   that is being returned to. The validation level is corrected to its 
   value when it called into the inner ring. This indicates a benign
   bug in the inner ring entry called.

   A:   $inform


   Message:
   ring_alarm$fault: Reset admin privileges.

   S:   $log

   T:   $run

   M:   On exit from ring one, one or more AIM privileges were still set
   by privileged ring 1 code. These are reset, and the following
   log message from set_privileges lists them. This indicates
   a benign bug in the ring one program that was running.

   A:   $inform

END MESSAGE DOCUMENTATION */

/* format: off */

%page; %include mc;
%page; %include apte;
%page; %include syserr_constants;
%page; %include its;
%page; %include signaller_stack;
%page; %include stack_frame;
%page; %include stack_header;
%page; %include syserr_binary_def;
     end ring_alarm;




		    set_alarm_timer.pl1             11/11/89  1106.6r   11/11/89  0813.4       62352



/****^  ***********************************************************
        *                                                         *
        * Copyright, (C) Honeywell Bull Inc., 1987                *
        *                                                         *
        * Copyright, (C) Honeywell Information Systems Inc., 1982 *
        *                                                         *
        * Copyright (c) 1972 by Massachusetts Institute of        *
        * Technology and Honeywell Information Systems, Inc.      *
        *                                                         *
        *********************************************************** */

/* format: style4,indattr,ifthenstmt,ifthen,idind35,^indcomtxt */

/* SET_ALARM_TIMER - This procedure establishes a simulated wakeup at
   a designated clock time.

   declare set_alarm_timer ext entry(fixed bin(71),fixed bin,fixed bin(71));
   call set_alarm_timer(time,asw,event_channel);

   1. time		time of event or wakeup(Input).

   2. asw		1 if time is relative to current time, 2 if time is absolute(Input).

   3. event_channel	is event channel over which wakeup is to be sent; 0 if IPS signal
   is to be sent(Input).

   Modified January 1985 by Keith Loepere to fix argument copying while masked.
   Modified November 1984 by M. Pandolf to include hc_lock
   Modified Spring '77 by RE Mullen for concurrent scheduler
   Coded by R. J. Feiertag on July 25, 1971		*/

set_alarm_timer: proc (atime, asw, aevent);

/* Parameters */

dcl  aevent			fixed bin (71) parameter; /* event channel for wakeup */
dcl  asw				fixed bin parameter;/* absolute or relative time */
dcl  atime			fixed bin (71) parameter; /* time of wakeup */

/* Variables */

dcl  current_time			fixed bin (71);	/* current clock time */
dcl  esw				fixed bin;	/* internal copy of absolute-relative time switch */
dcl  event			fixed bin (71);	/* internal copy of event channel */
dcl  naptep			ptr;		/* pointer to APT entry of next process in list */
dcl  oaptep			ptr;		/* pointer to APT entry of last process in list */
dcl  time				fixed bin (71);	/* internal copy of time of wakeup */
dcl  wire_arg			bit (72) aligned;	/* mask with pmut's nasty note or'ed into it */
dcl  wired_stack_ptr		pointer;		/* ptp, actually */

/* Based */

dcl  bit20			bit (20) based;

/* External */

dcl  pds$apt_ptr			ext ptr;		/* pointer to APT entry of this process */
dcl  tc_data$			ext;		/* traffic controller data base */
dcl  tc_data$alarm_timer_list		ext bit (18) aligned; /* offset to list of processes with alarms pending */
dcl  tc_data$next_alarm_time		ext fixed bin (71); /* time of next simulated alarm */

/* Entries */

dcl  pxss$lock_apt			entry ();		/* only way to touch apt lock */
dcl  pxss$unlock_apt		entry ();		/* only way to touch apt lock */
dcl  pmut$unwire_unmask		entry (bit (72) aligned, pointer);
dcl  pmut$wire_and_mask		entry (bit (72) aligned, pointer);

/* Misc */

dcl  (addr, bit, clock, fixed, ptr, rel) builtin;
%page;
	esw = asw;				/* copy relative-absolute time switch */
	go to join;				/* join common code */

/* SET_ALARM - This procedure is identical to set_alarm_timer except that only
   absolute times are accepted.				*/

set_alarm: entry (atime, aevent);

	esw = 2;					/* only absolute times */

join:
	current_time = clock;			/* get current time */
	if esw = 1 then time = current_time + atime;	/* calculate absolute time from relative */
	else time = atime;
	if time < current_time then time = current_time;	/* make sure time is current */
	event = aevent;				/* copy event channel */

	call pmut$wire_and_mask (wire_arg, wired_stack_ptr);

	aptep = pds$apt_ptr;			/* get pointer to APT entry */
	tcmp = addr (tc_data$);			/* get pointer to traffic controller meters */
	call pxss$lock_apt ();			/* TRAFFIC CONTROLLER LOCKED */
	if aptep -> apte.alarm_time then do;		/* this process already has a timer pending */
	     if tc_data$alarm_timer_list = rel (aptep) then
		tc_data$alarm_timer_list = aptep -> apte.alarm_time_thread;
						/* if this process first on list then thread it out */
	     else do;				/* not first on list */
		naptep = ptr (aptep, tc_data$alarm_timer_list); /* get pointer to first entry */
		do while (naptep -> apte.alarm_time_thread ^= rel (aptep));
						/* find this process's position in list */
		     naptep = ptr (naptep, naptep -> apte.alarm_time_thread); /* go to next entry */
		end;
		naptep -> apte.alarm_time_thread = aptep -> apte.alarm_time_thread; /* thread out of list */
	     end;
	     aptep -> apte.alarm_time_thread = ""b;	/* no alarm pending */
	     aptep -> apte.alarm_time = ""b;
	end;
	if addr (time) -> bit20 then go to finish;	/* time too large */
	oaptep, naptep = ptr (aptep, tc_data$alarm_timer_list); /* get pointer to first entry on list */
	if time <= fixed (oaptep -> apte.alarm_time, 54) | rel (oaptep) = ""b then
	     tc_data$alarm_timer_list = rel (aptep);	/* thread in at head of list */
	else do;					/* not first on list */
	     naptep = ptr (oaptep, oaptep -> apte.alarm_time_thread); /* get pointer to next entry */
	     do while (time > fixed (naptep -> apte.alarm_time, 54) & rel (naptep) ^= ""b);
						/* find position in list for this entry */
		oaptep = naptep;			/* new last entry is current entry */
		naptep = ptr (naptep, naptep -> apte.alarm_time_thread); /* get next entry */
	     end;
	     oaptep -> apte.alarm_time_thread = rel (aptep); /* thread into list */
	end;
	aptep -> apte.alarm_time_thread = rel (naptep);	/* complete the thread */
	aptep -> apte.alarm_time = bit (fixed (time, 54));/* fill in time of alarm */
	aptep -> apte.alarm_event = event;		/* fill in event channel */
	if time < tc_data$next_alarm_time then tc_data$next_alarm_time = time;
						/* update time of next alarm */
finish:

	call pxss$unlock_apt ();			/* TRAFFIC CONTROLLER UNLOCKED */
	call pmut$unwire_unmask (wire_arg, wired_stack_ptr);
	return;
%page;

/* GET_ALARM_TIMER - This entry returns the current value of the pending timer
and the associated event channel.

   declare get_alarm_timer ext entry(fixed bin(71),fixed bin(71));
   call get_alarm_timer(time,event_channel);

   1. time		timer of alarm(Output).

   2. event_channel		event channel for wakeup(Output).
						   */

get_alarm_timer: entry (atime, aevent);

	call pmut$wire_and_mask (wire_arg, wired_stack_ptr);

	aptep = pds$apt_ptr;			/* get pointer to APT entry */
	tcmp = addr (tc_data$);			/* get pointer to traffic control meters */
	call pxss$lock_apt ();			/* TRAFFIC CONTROLLER LOCKED */
	time = fixed (aptep -> apte.alarm_time, 54);	/* get time of alarm */
	event = aptep -> apte.alarm_event;		/* get event channel */
	call pxss$unlock_apt ();			/* TRAFFIC CONTROLLER UNLOCKED */
	call pmut$unwire_unmask (wire_arg, wired_stack_ptr);

	atime = time;				/* return values */
	aevent = event;
	return;
%page; %include apte;
%page; %include hc_lock;
%page; %include tcm;
     end;



		    bull_copyright_notice.txt       08/30/05  1008.4r   08/30/05  1007.3    00020025

                                          -----------------------------------------------------------


Historical Background

This edition of the Multics software materials and documentation is provided and donated
to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. 
as a contribution to computer science knowledge.  
This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology,
Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull
and Bull HN Information Systems Inc. to the development of this operating system. 
Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970),
renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership
of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for 
managing computer hardware properly and for executing programs. Many subsequent operating systems
incorporated Multics principles.
Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., 
as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. .

                                          -----------------------------------------------------------

Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without
fee is hereby granted,provided that the below copyright notice and historical background appear in all copies
and that both the copyright notice and historical background and this permission notice appear in supporting
documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining
to distribution of the programs without specific prior written permission.
    Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc.
    Copyright 2006 by Bull HN Information Systems Inc.
    Copyright 2006 by Bull SAS
    All Rights Reserved
