?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: Wait Services' ??
MODULE pmm$wait_services;
?? RIGHT := 110 ??

{   PURPOSE:
{     The purpose of this module is to package contained procedures
{     so that they execute with the privileges necessary to issue the
{     wait monitor request and be callable only upto ring 6.

{   DESIGN:
{     The procedures contained in this module have an execution bracket
{     of 1, 6.  The procedures are callable only from within their
{     execution bracket.

?? NEWTITLE := '  Global System Declarations', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc syc$monitor_request_codes
*copyc tmc$execution_ring_constants
*copyc osd$virtual_address
*copyc pme$insufficient_privilege
*copyc pme$unknown_recipient_task
*copyc ost$caller_identifier
*copyc ost$global_task_id
*copyc ost$hardware_subranges
*copyc tmt$preempted_reason
*copyc tmt$rb_wait
?? POP ??
*copyc osp$set_status_abnormal
*copyc tmp$wait
*copyc tmv$null_global_task_id
*copyc i#call_monitor
?? OLDTITLE ??
?? NEWTITLE := 'WAIT_REQUEST_CALC', EJECT ??

  PROCEDURE [INLINE] wait_request_calc
    (    requested_ms: 0 .. 0ffffffffffff(16);
         expected_ms: 0 .. 0ffffffffffff(16);
         global_taskid: ost$global_task_id;
     VAR wait: tmt$rb_wait);

    VAR
      time: ost$free_running_clock;

    time := #FREE_RUNNING_CLOCK (0);
    wait.reqcode := syc$rc_wait;

    IF (((requested_ms * 1000) + time) > UPPERVALUE (ost$free_running_clock)) THEN
      wait.requested_wait_time := UPPERVALUE (ost$free_running_clock);
    ELSE
      wait.requested_wait_time := (requested_ms * 1000) + time;
    IFEND;

    IF ((expected_ms * 1000) > UPPERVALUE (ost$free_running_clock)) THEN
      wait.expected_wait_time := UPPERVALUE (ost$free_running_clock);
    ELSE
      wait.expected_wait_time := expected_ms * 1000;
    IFEND;

    wait.global_taskid := global_taskid;

  PROCEND wait_request_calc;

?? TITLE := '  [XDCL, #GATE] pmp$wait', EJECT ??
*copyc pmh$wait

  PROCEDURE [XDCL, #GATE] pmp$wait
    (    requested_ms: 0 .. 0ffffffffffff(16);
         expected_ms: 0 .. 0ffffffffffff(16));

    VAR
      wait: tmt$rb_wait,
      global_taskid: ost$global_task_id,
      caller: ost$caller_identifier;

    #CALLER_ID (caller);
    global_taskid := tmv$null_global_task_id;

    IF (caller.ring < tmc$highest_recognition_ring) THEN
      tmp$wait (global_taskid, tmc$wait, requested_ms, expected_ms);
    ELSE
      wait_request_calc (requested_ms, expected_ms, global_taskid, wait);
      i#call_monitor (#LOC (wait), #SIZE (wait));
    IFEND;

  PROCEND pmp$wait;
?? TITLE := 'PMP$READY_TASK_AND_WAIT', EJECT ??

  PROCEDURE [XDCL, #GATE] pmp$ready_task_and_wait
    (    global_taskid: ost$global_task_id;
         requested_ms: 0 .. 0ffffffffffff(16);
         expected_ms: 0 .. 0ffffffffffff(16);
     VAR status: ost$status);

*copyc pmh$ready_task_and_wait

    VAR
      wait: tmt$rb_wait,
      caller: ost$caller_identifier;

    status.normal := TRUE;

    #CALLER_ID (caller);

    IF caller.ring > 6 THEN
      osp$set_status_abnormal ('PM', pme$insufficient_privilege, '', status);
      RETURN; {----->
    IFEND;

    IF (caller.ring < tmc$highest_signal_flag_ring) THEN
      tmp$wait (global_taskid, tmc$wait, requested_ms, expected_ms);
    ELSE
      wait_request_calc (requested_ms, expected_ms, global_taskid, wait);
      i#call_monitor (#LOC (wait), #SIZE (wait));
    IFEND;

    IF NOT wait.status.normal THEN
      osp$set_status_abnormal (pmc$program_management_id, pme$unknown_recipient_task, '', status);
    IFEND;

  PROCEND pmp$ready_task_and_wait;

?? TITLE := '  [XDCL, #GATE] pmp$long_term_wait', EJECT ??
*copyc pmh$long_term_wait

  PROCEDURE [XDCL, #GATE] pmp$long_term_wait
    (    requested_ms: 0 .. 0ffffffffffff(16);
         expected_ms: 0 .. 0ffffffffffff(16));

    VAR
      wait: tmt$rb_wait,
      global_taskid: ost$global_task_id,
      caller: ost$caller_identifier;

    #CALLER_ID (caller);
    global_taskid := tmv$null_global_task_id;

    IF (caller.ring < tmc$highest_recognition_ring) THEN
      tmp$wait (global_taskid, tmc$long_term_wait, requested_ms, expected_ms);
    ELSE
      wait_request_calc (requested_ms, expected_ms, global_taskid, wait);
      i#call_monitor (#LOC (wait), #SIZE (wait));
    IFEND;

  PROCEND pmp$long_term_wait;
MODEND pmm$wait_services;
