?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Device Management' ??
?? NEWTITLE := '  Module Header' ??
MODULE dmm$save_reconcile_list;

{
{ PURPOSE:
{
{  The purpose of this module is to create and maintain a list of all files known to
{  Device Manager at deadstart time. This is used to reconcile the files known to Permanent
{  File Manager with those known to Device Manager. The routines in this module are
{  only those required to run in ring 1 to have access to mainframe pageable.
{

?? TITLE := '  Common Decks', EJECT ??
*copyc dmt$reconcile_info
*copyc dmt$reconcile_locator
*copyc osd$virtual_address
*copyc ost$status
*copyc osv$mainframe_pageable_heap
*copyc oss$network_paged
*copyc ost$signature_lock
*copyc dmp$allocate_file_space_r1
*copyc gfp$get_segment_sfid
*copyc pmp$delay
*copyc pmp$get_microsecond_clock
*copyc syp$display_deadstart_message

?? TITLE := '  Global Declarations', EJECT ??

  VAR
    dmv$reconciliation_lock: [XDCL, #GATE, oss$network_paged] ost$signature_lock := [0],
    dmv$reconcile_locator: [XDCL, #GATE, oss$mainframe_pageable] dmt$reconcile_locator := NIL;

?? TITLE := '  dmp$save_reconcile_list', EJECT ??
*copyc dmh$save_reconcile_list

  PROCEDURE [XDCL, #GATE] dmp$save_reconcile_list
    (    reconcile_info: dmt$reconcile_info);

    CONST
      five_minutes = 1000000 * 60 * 5;

    VAR
      base: integer,
      clock: integer,
      local_stat: ost$status,
      p_reconcile_info: ^dmt$reconcile_info,
      p_sequence: ^SEQ ( * ),
      seq_size: ost$segment_length,
      status: ost$status,
      sfid: gft$system_file_identifier,
      p_subfile_list: dmt$p_reconcile_list;

    IF dmv$reconcile_locator <> NIL THEN
      FREE dmv$reconcile_locator IN osv$mainframe_pageable_heap^;
    IFEND;

    seq_size := #size(reconcile_info) + #size(reconcile_info.p_sorted_reconcile_list^);
    ALLOCATE p_sequence: [[REP seq_size of cell ]] IN osv$mainframe_pageable_heap^;
    {Table can be huge - could fill up memory with unwritable modified pages if not allocated
    gfp$get_segment_sfid (#LOC (p_sequence^), sfid, status);
    IF status.normal THEN
      pmp$get_microsecond_clock (base, local_stat);
      REPEAT
        pmp$get_microsecond_clock (clock, local_stat);
        dmp$allocate_file_space_r1 (sfid, #offset (p_sequence), seq_size, 0,
            osc$nowait, sfc$no_limit, status);
        IF NOT status.normal THEN
          pmp$delay (5000, local_stat);
        IFEND;
      UNTIL status.normal OR (clock > (base + five_minutes));
      IF NOT status.normal THEN
        syp$display_deadstart_message ('!! SYSTEM HUNG ATTEMPTING TO ALLOCATE');
        syp$display_deadstart_message ('!! MAINFRAME PAGEABLE SEGMENT........');
        syp$display_deadstart_message ('!! REDEADSTART WITHOUT JOB RECOVERY..');
        REPEAT
          pmp$delay (5000, local_stat);
        UNTIL FALSE;
      IFEND;
    IFEND;
    dmv$reconcile_locator := p_sequence;
    RESET p_sequence;
    NEXT p_reconcile_info IN p_sequence;
    NEXT p_subfile_list: [1 .. UPPERBOUND (reconcile_info.p_sorted_reconcile_list^)] IN p_sequence;

    p_reconcile_info^ := reconcile_info;
    p_reconcile_info^.p_sorted_reconcile_list := p_subfile_list;

    p_subfile_list^ := reconcile_info.p_sorted_reconcile_list^;
  PROCEND dmp$save_reconcile_list;

?? TITLE := '  dmp$update_reconcile_list', EJECT ??
*copyc dmh$update_reconcile_list

  PROCEDURE [XDCL, #GATE] dmp$update_reconcile_list
    (    subfile_index: dmt$reconcile_index;
         purge_file: boolean;
         reconciled: boolean);
    VAR
      p_reconcile_info: ^dmt$reconcile_info;

    p_reconcile_info := dmv$reconcile_locator;
    p_reconcile_info^.p_sorted_reconcile_list^[subfile_index].purge := purge_file;
    p_reconcile_info^.p_sorted_reconcile_list^[subfile_index].reconciled := reconciled;
  PROCEND dmp$update_reconcile_list;

MODEND dmm$save_reconcile_list;

