Google
 

Trailing-Edge - PDP-10 Archives - BB-X117B-SB_1986 - 10,7/nml/nmutbl.bli
There are 3 other files named nmutbl.bli in the archive. Click here to see a list.
! NET:<GROSSMAN>NMUTBL.BLI.2 16-Feb-82 16:11:28, Edit by GROSSMAN
!
! Fix a dot bug in TABLE_CLEAR. It caused the table block to be released twice
! which is a no no.
!
! NET:<PECKHAM.DEVELOPMENT>NMUTBL.BLI.2 13-Feb-82 22:39:41, Edit by PECKHAM
!
! Ident 02.
! Fix argument ordering on NMU$MEMORY_RELEASE in NMU$TABLE_CLEAR.
!
! NET:<DECNET20-V3P1.NMU>NMUTBL.BLI.2 23-Jun-81 09:00:21, Edit by JENNESS
!
!    Readability improvements.  Correct copyright date.  Add
!    NMU$TABLE_MAX routine.
module NMUTBL (                         ! Table data base manager
		ident = 'X00.02'
		) =
begin

!
!                       COPYRIGHT (C) 1981 BY
!    DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS  01754
!
! THIS SOFTWARE IS FURNISHED  UNDER A LICENSE FOR USE ONLY ON A SINGLE
! COMPUTER  SYSTEM AND  MAY BE  COPIED ONLY WITH  THE INCLUSION OF THE
! ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE, OR ANY OTHER COPIES  THEREOF
! MAY NOT BE PROVIDED OR  OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON
! EXCEPT FOR USE ON SUCH SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE
! TERMS.  TITLE TO AND  OWNERSHIP OF THE  SOFTWARE  SHALL AT ALL TIMES
! REMAIN IN DEC.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
! AND SHOULD  NOT BE CONSTRUED  AS A COMMITMENT  BY DIGITAL  EQUIPMENT
! CORPORATION.
!
! DEC ASSUMES  NO  RESPONSIBILITY  FOR  THE USE OR  RELIABILITY OF ITS
! SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC.
!
!++
!
! Facility: LSG DECnet Management
!
! Abstract: This set of routines manages a table data base.  This data base
!           is a linked list of tables.  To the outside world it looks like
!           a table manager that has a very large (infinite until memory
!           runs out) vector.
!
!           Insertion - A free cell in any existing table is assigned
!                       to the specified value.  The index (absolute
!                       from start of the data base) is returned.
!
!           Fetch -     A index into the data base is used to search
!                       for a entry in one of the linked tables.
!
!           Delete -    A index into the data base is used to search
!                       for a entry that is to be made available for
!                       subsequent insertions.
!
!           Change -    A index into the data base is used to search
!                       for a entry whose value is changed.
!
!           Clear -     The storage used by a table data base is released
!                       to the memory manager.
!
!           Max -       Return the maximum index currently available
!                       in the table data base (not necessarily used).
!
! Environment: TOPS20, TOPS10 or MCB RSX task
!
! Author: Steven M. Jenness	Creation date: 30-Mar-81
!
! Modified by:
!
!--
!
! Include files
!

library 'NMULIB';                       ! Get all required definitions

!
! Global routines
!

forward routine
    NMU$TABLE_ROUTINES;                   ! Declare global entries

!
! Equated symbols
!

literal
       MAX_INDEX_PER_BLOCK = 16;

!
! Structure definitions
!

$field
      TABLE_BLOCK_FIELDS =
      set
      TBL_FIRST = [$integer],           ! First index in this block
      TBL_LAST = [$integer],            ! Last index in this block
      TBL_FLAGS = [$bits (MAX_INDEX_PER_BLOCK)], ! Entry allocated flags
      TBL_NEXT = [$address],            ! Address of next table block
      TBL_DATA = [$sub_block (0)]       ! Beginning of data array
      tes;

literal
       TABLE_FIELDS_SIZE = $field_set_size,
       TABLE_BLOCK_ALLOCATION =
             $field_set_units + (MAX_INDEX_PER_BLOCK * %upval);

macro
     TABLE_BLOCK = block [TABLE_FIELDS_SIZE] field (TABLE_BLOCK_FIELDS) %;

macro
     TABLE_FLAGS = bitvector [16] %;

!
! External references
!

external routine
         NMU$MEMORY_MANAGER;

%global_routine ('NMU$TABLE_CLEAR', TABLE_BASE) : novalue =

!++
! Functional description:
!
!        This routine clears a table data base.  It releases all
!        table blocks to the memory manager.
!
! Formal parameters:
!
!        .TABLE_BASE  Address of table base cell
!
! Implicit inputs: none
! Implicit outputs:
!
!        ..TABLE_BASE is set to zero
!
! Routine value: none
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK,
         OLD_TABLE;

    TABLE = ..TABLE_BASE;
    .TABLE_BASE = 0;

    while (OLD_TABLE = .TABLE) neq 0
    do
      begin
      TABLE = .TABLE [TBL_NEXT];
      NMU$MEMORY_RELEASE (.OLD_TABLE, TABLE_BLOCK_ALLOCATION);
      end;

    end;					! End of NMU$TABLE_CLEAR
%global_routine ('NMU$TABLE_INSERT', TABLE_BASE, VALUE) =

!++
! Functional description:
!
!        This routine inserts a value into a table data base.  It searches
!        all the linked tables for a free entry to use.  If no free entry
!        exists, it creates a new table block and links it at the end of the
!        table list.  The index returned is used for any future reference
!        to the table data base entry.
!
! Formal parameters:
!
!        .TABLE_BASE    Address of cell containing base address of table list
!        .VALUE         Fullword value to be inserted into list
!
! Routine value:
!
!        Index value into table data base
!
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK,
         PREV_TABLE : ref TABLE_BLOCK,
         INDEX, LOCAL_INDEX;
!
! Point to the first table block in the table list.
! Indicate that there is no previously seen table block.
!
    TABLE = ..TABLE_BASE;
    PREV_TABLE = 0;
!
! Search list of table blocks for one that hasn't been
! completely filled.  If an unallocated entry is found,
! put the specified value into and flag it taken.
!
    until .TABLE eql 0
    do
      if .TABLE [TBL_FLAGS] eql 0
      then
          begin
          PREV_TABLE = .TABLE;
          TABLE = .TABLE [TBL_NEXT];
          end
      else
          begin
          bind
              FLAGS = TABLE [TBL_FLAGS] : TABLE_FLAGS,
              TABLE_DATA = TABLE [TBL_DATA] : vector [MAX_INDEX_PER_BLOCK];

          incr I from 1 to MAX_INDEX_PER_BLOCK
          do
            if .FLAGS [.I - 1] eql 1
            then
                begin
                FLAGS [.I - 1] = 0;
                TABLE_DATA [.I - 1] = .VALUE;
                return (.TABLE [TBL_FIRST] + .I - 1);
                end;
          end;

    TABLE = NMU$MEMORY_GET (TABLE_BLOCK_ALLOCATION);

    if .PREV_TABLE eql 0
    then
        begin
        TABLE [TBL_FIRST] = 1;
        .TABLE_BASE = .TABLE;
        end
    else
        begin
        TABLE [TBL_FIRST] = .PREV_TABLE [TBL_FIRST] + MAX_INDEX_PER_BLOCK;
        PREV_TABLE [TBL_NEXT] = .TABLE;
        end;

    TABLE [TBL_LAST] = .TABLE [TBL_FIRST] + MAX_INDEX_PER_BLOCK - 1;
    TABLE [TBL_FLAGS] = -1;

    begin
    bind
        FLAGS = TABLE [TBL_FLAGS] : TABLE_FLAGS,
        TABLE_DATA = TABLE [TBL_DATA] : vector [MAX_INDEX_PER_BLOCK];

    FLAGS [0] = 0;
    TABLE_DATA [0] = .VALUE;

    end;

    .TABLE [TBL_FIRST]

    end;					! End of NMU$TABLE_INSERT
%global_routine ('NMU$TABLE_FETCH', TABLE_BASE, INDEX, VALUE) =

!++
! Functional description:
!
!        This routine gets a fullword value from the specified table data
!        base.  The index passed is used to search the data base for the
!        appropriate value.
!
! Formal parameters:
!
!        .TABLE_BASE    Address of cell containing base address of table
!        .INDEX         Index number into data base
!
! Implicit inputs: none
! Implicit outputs:
!
!        VALUE    Value found in data base
!
! Routine value:
!
!        $true    Index is valid, output register VALUE contains value
!        $false   Index is invalid
!
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK;

    TABLE = ..TABLE_BASE;

    until .TABLE eql 0
    do
      if (.INDEX geq .TABLE [TBL_FIRST]) and (.INDEX leq .TABLE [TBL_LAST])
      then
          begin
          bind
              FLAGS = TABLE [TBL_FLAGS] : TABLE_FLAGS,
              TABLE_DATA = TABLE [TBL_DATA] : vector [MAX_INDEX_PER_BLOCK];

          if .FLAGS [.INDEX - .TABLE [TBL_FIRST]] eql 0
          then
              begin
              .VALUE = .TABLE_DATA [.INDEX - .TABLE [TBL_FIRST]];
              return $true;
              end
          else
              return $false;
          end
      else
          TABLE = .TABLE [TBL_NEXT];

    $false
    end;					! End of NMU$TABLE_FETCH
%global_routine ('NMU$TABLE_DELETE', TABLE_BASE, INDEX) =

!++
! Functional description:
!
!        This routine frees up a specified table data base entry.
!
! Formal parameters:
!
!        .TABLE_BASE    Address of cell containing base address of table
!        .INDEX         Index number into data base
!
! Routine value:
!
!        $true    Index was valid, entry deleted
!        $false   Index was invalid
!
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK;

    TABLE = ..TABLE_BASE;

    until .TABLE eql 0
    do
      if (.INDEX geq .TABLE [TBL_FIRST]) and (.INDEX leq .TABLE [TBL_LAST])
      then
          begin
          bind
              FLAGS = TABLE [TBL_FLAGS] : TABLE_FLAGS;

          FLAGS [.INDEX - .TABLE [TBL_FIRST]] = 1;
          return $true;
          end
      else
          TABLE = .TABLE [TBL_NEXT];

    $false
    end;					! End of NMU$TABLE_DELETE
%global_routine ('NMU$TABLE_CHANGE', TABLE_BASE, INDEX, VALUE) =

!++
! Functional description:
!
!        This routine changes a value associated with a particular
!        index in the table data base.  It assumes that a value
!        was previously inserted and assigned the specified index.
!
! Formal parameters:
!
!        .TABLE_BASE    Address of cell containing base address of table
!        .INDEX         Index number into data base
!        .VALUE         New value to insert
!
! Routine value:
!
!        $true    Index was valid, value changed
!        $false   Index was invalid, no change made
!
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK;

    TABLE = ..TABLE_BASE;

    until .TABLE eql 0
    do
      if (.INDEX geq .TABLE [TBL_FIRST]) and (.INDEX leq .TABLE [TBL_LAST])
      then
          begin
          bind
              FLAGS = TABLE [TBL_FLAGS] : TABLE_FLAGS,
              TABLE_DATA = TABLE [TBL_DATA] : vector [MAX_INDEX_PER_BLOCK];

          if .FLAGS [.INDEX - .TABLE [TBL_FIRST]] eql 0
          then
              begin
              TABLE_DATA [.INDEX - .TABLE [TBL_FIRST]] = .VALUE;
              return $true;
              end
          else
              return $false;
          end
      else
          TABLE = .TABLE [TBL_NEXT];

    $false
    end;					! End of NMU$TABLE_CHANGE
%global_routine ('NMU$TABLE_MAX', TABLE_BASE) =

!++
! Functional description:
!
!        This routine returns the maximum table index currently
!        available.  It does not imply that the returned value
!        is the maximum allocated index.
!
! Formal parameters:
!
!        .TABLE_BASE    Address of cell containing base address of table
!
! Routine value:
!
!        <>0    Maximum table index
!         =0    No table yet
!
! Side effects: none
!
!--

    begin
    local
         TABLE : ref TABLE_BLOCK,
         HIGHEST_TABLE : ref TABLE_BLOCK;

!
! Start at the beginning table block in the table.
! If no table has been started return a zero max index.
!
    if (TABLE = ..TABLE_BASE) eql 0
    then return 0;

!
! Search to the end of the table
!
    until .TABLE eql 0
    do
      begin
      HIGHEST_TABLE = .TABLE;                    
      TABLE = .TABLE [TBL_NEXT];
      end;

!
! Return highest index from last found table block
!
    .HIGHEST_TABLE [TBL_LAST]

    end;					! End of NMU$TABLE_MAX

end						! End of NMUTBL
eludom