?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE job management recovery interfaces', ??
MODULE jmm$save_recovery_information;

{ PURPOSE:
{   This module contains the interfaces used to save information in the address
{   space of the job that is required in order to recover the job.
{
{ DESIGN:
{   Information required only for recovery by a job should not be part of the
{ job's working set but needs to be in the job's address space.  The recovery
{ information saved is in the job pageable segment.  Using aligned allocation
{ in job pageable, the information begins on a page boundary and always consists
{ of an allocation that is an integral number of pages.  After being updated,
{ this information is written to disk (without wait) and the page(s) can be
{ removed from the job's working set.  The procedures in this module execute
{ in ring 2.

?? NEWTITLE := 'Global Declarations Referenced by this Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc jmt$job_recovery_information
*copyc oss$job_pageable
*copyc ost$status
?? POP ??
*copyc mmp$write_modified_pages
*copyc osv$job_pageable_heap
*copyc osv$page_size
?? OLDTITLE ??
?? NEWTITLE := 'Global Variables Declared by this Module', EJECT ??

  VAR
    jmv$job_recovery_information_p: [XDCL, #GATE, oss$job_pageable] ^jmt$job_recovery_information := NIL;

?? OLDTITLE ??
?? NEWTITLE := 'allocate_recovery_information', EJECT ??
{ PURPOSE:
{   The purpose of this request is to allocate job recovery information in the
{ job pageable segment.

  PROCEDURE allocate_recovery_information;

{ The type integral_pages is aligned on a large page size.  This will force any
{ the structure to begin on a page boundary when the page size is anywhere up
{ to 65,536 bytes.  If the page size is larger than this value, this type may
{ need to change.  When changing the alignment value to a larger value, keep in
{ mind the amount of data being saved in comparison to the page size.  If the
{ page size is 20 times greater than the amount of information being saved, it
{ is probably not useful to change this type.

    TYPE
      integral_pages = record
        bytes: ALIGNED [0 MOD 65536] array [1 .. * ] of cell,
      recend;

    VAR
      converter_p: ^cell,
      recovery_info_size_in_bytes: integer,
      recovery_information_p: ^integral_pages;

    IF jmv$job_recovery_information_p = NIL THEN
      recovery_info_size_in_bytes := osv$page_size;
      WHILE recovery_info_size_in_bytes < #SIZE (jmt$job_recovery_information) DO
        recovery_info_size_in_bytes := recovery_info_size_in_bytes + osv$page_size;
      WHILEND;

      ALLOCATE recovery_information_p: [1 .. recovery_info_size_in_bytes] IN osv$job_pageable_heap^;
      converter_p := recovery_information_p;
      jmv$job_recovery_information_p := converter_p;
    IFEND;
  PROCEND allocate_recovery_information;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$save_recovery_information', EJECT ??
*copy jmh$save_recovery_information

  PROCEDURE [XDCL, #GATE] jmp$save_recovery_information
    (    job_system_label_p: ^jmt$job_system_label);

    allocate_recovery_information;
    jmv$job_recovery_information_p^.job_system_label := job_system_label_p^;
  PROCEND jmp$save_recovery_information;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] jmp$write_recovery_info_to_disk', EJECT ??
*copy jmh$write_recovery_info_to_disk
{ DESIGN:
{   When the pages have been written to disk they are taken out of the job's
{ working set and placed in the available queue.

  PROCEDURE [XDCL, #GATE] jmp$write_recovery_info_to_disk;

    VAR
      ignore_status: ost$status;

    IF jmv$job_recovery_information_p <> NIL THEN
      mmp$write_modified_pages (jmv$job_recovery_information_p, #SIZE (jmt$job_recovery_information),
            osc$nowait, ignore_status);
    IFEND;
  PROCEND jmp$write_recovery_info_to_disk;
?? OLDTITLE ??
MODEND jmm$save_recovery_information;

