MODULE dmm$allocate_avt;
?? RIGHT := 110 ??

{ PURPOSE:
{      This module contains the procedures used to allocate the AVT.

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$mainframe_paged_literal
*copyc dmt$active_volume_table_index
?? POP ??
*copyc osp$clear_mainframe_sig_lock
*copyc osp$set_mainframe_sig_lock
*copyc dmv$active_volume_table
*copyc osv$mainframe_wired_heap
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared By This Module', EJECT ??

  VAR
    v$default_avt_entry: [STATIC, READ, oss$mainframe_paged_literal] dmt$active_volume_table_entry := [
{LOCK                             } [0],
{ENTRY_AVAILABLE                  } FALSE,
{LOGICAL_UNIT_NUMBER              } 0,
{PADDING                          } 'AVTE',
{ALLOCATION_ALLOWED               } [FALSE,
{SPACE_LOW                        } FALSE,
{SPACE_GONE                       } FALSE,
{DISK_TABLE_STATUS                } $dmt$ms_volume_table_status [],
{CLASS                            } $dmt$class [],
{SYSTEM_CLASS_ACTIVITY            } [0, 0, 0, 0, 0],
{LOGGED_IN_FOR_RECOVERY           } FALSE,
{UPDATE_LOCK                      } [0],
{LOGGING_LOCK                     } [0],
{INTERNAL_VSN                     } [0, osc$cyber_180_model_unknown, 1980, 1, 1, 0, 0, 0, 0, 0],
{P_DEVICE_ALLOCATION_TABLE        } [0, gfc$tr_null_residence, gfc$null_file_hash],
{P_DEVICE_FILE_LIST_TABLE         } [0, gfc$tr_null_residence, gfc$null_file_hash],
{P_DEVICE_LOG                     } [0, gfc$tr_null_residence, gfc$null_file_hash],
{P_DIRECTORY                      } [0, gfc$tr_null_residence, gfc$null_file_hash],
{P_LOGIN_TABLE                    } [0, gfc$tr_null_residence, gfc$null_file_hash],
{MAINFRAME_ASSIGNED               } [0, 1],
{P_MAT                            } [NIL, 0, 0, 0],
{P_MFL                            } [NIL, 0, 0, 0],
{RECORDED_VSN                     } '      ',
{SET_NAME                         } osc$null_name,
{STATUS                           } $dmt$ms_volume_system_status [],
{VOLUME_OWNER                     } [osc$null_name, osc$null_name],
{CURRENT_POSITION_OFFSET_IN_LOG   } 0,
{ALLOCATED_LOG_SIZE               } 0,
{DEVICE_LOG_ENTRY_COUNT           } 0,
{VOLUME_UNAVAILABLE               } FALSE,
{VOLUME_UNAVAILABLE_MSG           } FALSE,
{LOGGING_PROCESS_DAMAGED          } FALSE]];

?? NEWTITLE := '[xdcl] DMP$ALLOCATE_AVT', EJECT ??

  PROCEDURE [XDCL] dmp$allocate_avt
    (    avt_count: integer;
     VAR allocate_ok: boolean);

    VAR
      avt_index: integer,
      avt_limit: integer,
      free_p: ^dmt$active_volume_table_entries,
      temp_avt_p: ^dmt$active_volume_table_entries;

    allocate_ok := FALSE;
    osp$set_mainframe_sig_lock (dmv$active_volume_table.lock);

    avt_limit := UPPERBOUND (dmv$active_volume_table.table_p^);

    IF avt_count > avt_limit THEN
      ALLOCATE temp_avt_p: [1 .. avt_count] IN osv$mainframe_wired_heap^;

{ Copy current entries to new array. }
      FOR avt_index := 1 TO avt_limit DO
        temp_avt_p^ [avt_index] := dmv$active_volume_table.table_p^ [avt_index];
      FOREND;

{ Initialize new entries. }
      FOR avt_index := avt_limit + 1 TO avt_count DO
        temp_avt_p^ [avt_index] := v$default_avt_entry;
        temp_avt_p^ [avt_index].entry_available := TRUE;
      FOREND;

      free_p := dmv$active_volume_table.table_p;
      dmv$active_volume_table.table_p:= temp_avt_p;
      FREE free_p IN osv$mainframe_wired_heap^;

      allocate_ok := TRUE;
    ELSE
      allocate_ok := TRUE; { No need to allocate since this is the case of one disk.
    IFEND;

    osp$clear_mainframe_sig_lock (dmv$active_volume_table.lock);

  PROCEND dmp$allocate_avt;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] DMP$GET_UNUSED_AVT_ENTRY', EJECT ??
*copy dmh$get_unused_avt_entry

  PROCEDURE [XDCL] dmp$get_unused_avt_entry
    (VAR avt_index: dmt$active_volume_table_index;
     VAR able_to_get_avt_entry: boolean);

    VAR
      entry_p: ^dmt$active_volume_table_entry;

    able_to_get_avt_entry := FALSE;
    osp$set_mainframe_sig_lock (dmv$active_volume_table.lock);

  /search_entry/
    FOR avt_index := LOWERBOUND (dmv$active_volume_table.table_p^)
          TO UPPERBOUND (dmv$active_volume_table.table_p^) DO
      entry_p := ^dmv$active_volume_table.table_p^ [avt_index];
      IF entry_p^.entry_available THEN
        entry_p^ := v$default_avt_entry;
        able_to_get_avt_entry := TRUE;
        EXIT /search_entry/; {----->
      IFEND;
    FOREND /search_entry/;

    osp$clear_mainframe_sig_lock (dmv$active_volume_table.lock);

  PROCEND dmp$get_unused_avt_entry;
?? OLDTITLE ??
?? NEWTITLE := '[xdcl] DMP$RELEASE_AVT_ENTRY', EJECT ??
*copy dmh$release_avt_entry

  PROCEDURE [XDCL] dmp$release_avt_entry
    (    avt_index: dmt$active_volume_table_index;
     VAR able_to_release_avt_entry: boolean);

    VAR
      able_to_lock_avt_entry: boolean;

    able_to_release_avt_entry := FALSE;
    osp$set_mainframe_sig_lock (dmv$active_volume_table.lock);

    IF avt_index > 0 THEN
      IF NOT dmv$active_volume_table.table_p^ [avt_index].entry_available THEN
        dmv$active_volume_table.table_p^ [avt_index].entry_available := TRUE;
        able_to_release_avt_entry := TRUE;
      IFEND;
    IFEND;

    osp$clear_mainframe_sig_lock (dmv$active_volume_table.lock);

  PROCEND dmp$release_avt_entry;
?? OLDTITLE ??
MODEND dmm$allocate_avt;
