Trailing-Edge
-
PDP-10 Archives
-
RMS-10_T10_704_FT2_880425
-
10,7/rms10/rmssrc/rmsfsm.b36
There are 6 other files named rmsfsm.b36 in the archive. Click here to see a list.
MODULE FSM =
BEGIN
GLOBAL BIND FSMV = 1^24 + 0^18 + 4; !EDIT DATE: 6-JUL-78
%([
FUNCTION: THIS MODULE CONTAINS ALL ROUTINES AND STRUCTURES
WHICH PROCESS AND DESCRIBE THE RMS-20 FREE STORAGE
MANAGER (FSM). CURRENTLY, ALL FREE STORAGE IS
MANAGED BY RMS-20 ITSELF. THE AMOUNT OF FREE STORAGE
IS A SYSTEM-BUILD PARAMETER AND CANNOT BE CHANGED ONCE
RMS-20 IS LOADED AND INITIALIZED.
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
!COPYRIGHT (C) 1977, 1979 BY DIGITAL EQUIPMENT CORPORATION
AUTHOR: S. BLOUNT
********** TABLE OF CONTENTS ***********
ROUTINE FUNCTION
======= ========
GPAGE ALLOCATE A FREE PAGE
PPAGE RELEASE A FREE PAGE
GMEM ALLOCATE A BLOCK OF FREE MEMORY
PMEM RELEASE A BLOCK OF FREE MEMORY
REVISION HISTORY:
EDIT DATE WHO PURPOSE
==== ==== === =========
1 OCT-18-76 SB FIX SYNTAX BUG IN GPAGE FOR MULTIPLE PAGES
*************************************************
* *
* NEW REVISION HISTORY *
* *
*************************************************
PRODUCT MODULE SPR
EDIT EDIT QAR DESCRIPTION
====== ====== ===== ===========
14 2 11723 THE PAGE LINK CONSISTENCY CHECK IN GMEM
IS INCORRECT, SUCH THAT ONCE CORE
BECOMES FRAGMENTED, IT WILL ALWAYS FAIL.
****************** Start RMS-10 V1.1 *********************
********************* TOPS-10 ONLY ***********************
PRODUCT MODULE SPR
EDIT EDIT QAR DESCRIPTION
====== ====== ===== ===========
100 3 Dev Make declarations for routine names
be EXTERNAL ROUTINE so RMS will compile
under BLISS V4 (RMT, 10/22/85).
102 4 Dev Change checks for RMS$$G to be for less
than 643000, so that RMS$$G can be assigned
higher to avoid symbol conflicts under
BLISS V4 (RMT, 12/2/85).
***** END OF REVISION HISTORY *****
])%
%([ EXTERNAL DECLARATIONS ])%
EXTERNAL ROUTINE
FGPAGE, ! ENTRY POINT IN FUNCT. TO GET A PAGE
FGMEM, ! ENTRY POINT IN FUNCT. TO GET BLOCK OF MEM.
FPMEM, ! ENTRY POINT IN FUNCT. TO FREE MEM.
CRASH,
DUMP;
EXTERNAL
RMS$$G, !LOCATION OF RMS GLOBALS. THEY GO IN ONE OF 3 LOCS
!LOWSEG (RMS.REL WITH COBOL/R)
!573000 (RMSCOB.EXE)
!643000 (RMS.EXE) -- THIS CASE ONLY USE RMS'S OWN FSM
NUMFREEPAGES;
%([ ERROR MESSAGE REFERENCES IN THIS MODULE ])%
EXTERNAL
MSGBSP,
MSGPM2, ! BIGHOL IS NON-ZERO
MSGBSTATUS, ! BAD RETURNED BY GMEM
MSGPM3, ! BAD VALUE FOUND IN PMEM
MSGINPUT, ! BAD INPUT VALUE
MSGLINK, ! LINK INCONSISTENCY
MSGCORE, ! CANT GET CORE
MSGPNA; ! PAGE NOT ALLOCATED
REQUIRE 'RMSREQ';
EXTDECLARATIONS;
%([
***********************************************************************
* FREE-CORE MANAGER STRUCTURES *
***********************************************************************
])%
%([ THERE ARE TWO PRIMARY DATA STRUCTURES USED BY THE FSM
TO MANAGE FREE STORAGE---THE PAGE TABLE, AND THE FREE
CORE CHUNKS THEMSELVES.
THE PAGE TABLE IS BUILT AT RMS COMPILE-TIME AND IS CONTAINED
WITHIN THE MODULE "RMSGLB". IT HAS ONE WORD FOR EACH PAGE
WHICH IS ALLOCATED TO THE FSM. THE FORMAT OF EACH WORD IN THE
PAGE TABLE IS AS FOLLOWS:
FORMAT OF PAGE TABLE ENTRY
!=====================================!
!*! BIGHOL ! FIRSTFREE !
!=====================================!
* = BUSY BIT:
0==>PAGE IS AVAILABLE FOR ALLOCATION
1==>PAGE WAS ALLOCATED BY GPAGE...IT IS BUSY
FREE CORE CHUNKS ARE FORMATTED SUCH THAT EACH CHUNK CONTAINS
A HEADER WHICH DESCRIBES THE SIZE OF THE CHUNK, AND THE ADDRESS
OF THE NEXT FREE CHUNK IN THE PAGE. THE HEADER IS ALWAYS AT THE
BOTTOM OF THE CHUNK (I.E., AT THE HIGHER MEMORY ADDRESS).
THE FORMAT OF A CHUNK HEADER IS AS FOLLOWS:
FORMAT OF CORE CHUNK HEADER
!=====================================!
! HOLESIZE ! FREEPTR !
!=====================================!
])%
%([ STRUCTURE OF EACH ENTRY IN THE PAGE TABLE ])%
MACRO FCMBUSY = 35,1%, ! BIT 0 MEANS PAGE NOT FREE
BIGHOL = 18,10%, ! LARGEST HOLE ON PAGE
FIRSTFREE = 0,18%; ! FIRST FREE CHUNK ON PAGE
%([ STRUCTURE OF EACH CHUNK HEADER ON A FREE PAGE ])%
MACRO HOLESIZE = 0,LH%, ! SIZE OF THIS HOLE
FREEPTR = 0,RH %; ! ADDRESS OF NEXT HOLE
! GPAGE
! =====
! THIS ROUTINE ALLOCATES CONSECUTIVE PAGES FROM THE POOL OF FREE CORE.
! NO CHOICE OF A SPECIFIC PAGE IS ALLOWED.
!
! INPUT:
! # OF CONTIGUOUS PAGES TO ALLOCATE
! OUTPUT:
! PAGE # OF 1ST PAGE IN GROUP
! RETURN FALSE IF NONE AVAILABLE
GLOBAL ROUTINE GPAGE ( PAGES ) =
BEGIN
ARGUMENT (PAGES,VALUE);
REGISTER
PAGENUM,
PAGECOUNT;
TRACE ( 'GPAGE' );
CHECKINPUT(PAGES,GTR,ZERO); ! PAGES MUST BE POSITIVE
%([ CODE TO UTILIZE OTS'S MEMORY MANAGER. TEMPORARY SOLUTION. ])%
%([ THE ROUTINES THAT CALL ON LIBOL'S MEMORY MANAGER ARE IN A ])%
%([ SEPERATE MODULE CALLED RMSOTS.MAC. THE ROUTINES IN THIS ])%
%([ MODULE ARE APPROPRIATELY NAMED FGPAGE, FGMEM AND FPMEM ])%
IF (RMS$$G LSS %O'643000')
THEN
BEGIN %(WE ARE PROBABLY LOADED BELOW 600000 FOR COBOL V12B)%
IF ( PAGENUM = $CALL ( FGPAGE, .PAGES ^ P2W )) IS FALSE
THEN
BADRETURN
ELSE
BEGIN
RETURN .PAGENUM
END
END;
%([ END OF CODE TO UTILIZE OTS'S MEMORY MANAGER ])%
PAGENUM = ZERO; ! START AT FIRST PAGE
%([ LOOP OVER ALL PAGES IN THE PAGE TABLE ])%
WHILE (.PAGENUM LEQ .NUMFREEPAGES - .PAGES) ! UNTIL LAST PAGE
DO
BEGIN %( CHECK IF BLOCK BEGINS HERE )%
PAGECOUNT = ZERO; ! CHECK FOR EACH PAGE OF BLOCK
WHILE (.PAGTAB [ .PAGENUM , FCMBUSY ] IS OFF )
DO
BEGIN %( THIS PAGE IS FREE. CHECK FOR REST OF BLOCK )%
IF ( .PAGECOUNT + 1 GEQ .PAGES )
THEN
BEGIN %( SET BUSY FOR ALL PAGES IN BLOCK )%
DECR PAGECOUNT FROM .PAGENUM
TO .PAGENUM - .PAGES + 1
BY 1
DO
BEGIN %( SET BUSY )%
PAGTAB [ .PAGECOUNT , wrd ] = ZERO;
PAGTAB [ .PAGECOUNT , FCMBUSY ] = ON
END; %( OF SET BUSY )%
$CALL (CREPAGE, .PAGENUM-.PAGES+1+.FRECOR,.PAGES);
RETURN ( .PAGENUM - .PAGES + 1 + .FRECOR)
END; %( OF SET BUSY FOR ALL PAGES OF BLOCK )%
PAGENUM = .PAGENUM + 1; ! INCR PAGTAB INDEX
PAGECOUNT = .PAGECOUNT + 1 ! COUNT NO. PAGES WE FOUND
END; %( OF THIS PAGE IS FREE )%
PAGENUM = .PAGENUM + 1
END; %( OF CHECK IF BLOCK BEGINS HERE )%
BADRETURN ! NO ROOM, GIVE FAILURE RETURN
END; %( OF GPAGE)%
! PPAGE
! =====
! THIS ROUTINE RETURNS CONSECUTIVE FULL PAGES TO FREE CORE
! THE PAGES MUST HAVE BEEN ALLOCATED BY GPAGE
! INPUT:
! PAGE # OF 1ST PAGE
! # OF PAGES TO RETURN
! DESTROY-FLAG ( TRUE MEANS DESTROY THIS PROCESS PAGE )
! OUTPUT:
! <NONE>
GLOBAL ROUTINE PPAGE ( PAGENUM, PAGES, KILLFLAG ) =
BEGIN
ARGUMENT (PAGENUM,VALUE);
ARGUMENT (PAGES,VALUE);
ARGUMENT (KILLFLAG,VALUE);
LOCAL
PAGEINDEX;
TRACE ( 'PPAGE' );
CHECKINPUT(PAGES,GTR,ZERO); ! MUST BE POSITIVE NO. PAGES
%([ Code to utilize OTS's memory manager. ])%
IF (RMS$$G LSS %O'643000')
THEN BEGIN %( WE ARE LOADED BELOW 600000 )%
IF $CALL ( FPMEM, .PAGENUM ^ P2W, .PAGES ^ P2W )
THEN GOODRETURN
ELSE RMSBUG ( MSGINPUT);
END;
%([ End of code to utilize OTS's memory manager ])%
%([ LOOP THRU ALL PAGES IN THE CHUNK WHICH IS BEING RETURNED ])%
INCR PAGEINDEX FROM .PAGENUM - .FRECOR
TO .PAGENUM - .FRECOR + .PAGES - 1
BY 1
DO
BEGIN %( REMOVE THIS PAGE )%
IF ( .PAGTAB [ .PAGEINDEX , FCMBUSY ] IS OFF )
THEN RMSBUG ( MSGPNA ); ! ** PAGE NOT AVAILABLE **
PAGTAB [ .PAGEINDEX , wrd ] = ZERO;
%([ SHOULD WE DESTROY THIS PAGE? ])%
IF ( .KILLFLAG )
THEN $CALL (KILLPAGE, .PAGEINDEX+.FRECOR, 1);
END; %( OF REMOVE THIS PAGE )%
GOODRETURN
END; %( OF PPAGE)%
! GMEM
! ====
! THIS ROUTINE ALLOCATES CORE FROM THE FREE POOL IN
! VARIABLE-SIZED CHUNKS. EACH REQUEST MUST
! BE FOR LESS THAN 1 PAGE. IF MORE THAN
! ONE PAGE IS REQUIRED, THE CALLER MUST
! COMPUTE HIS NEEDS ALL CALL GPAGE FOR THE
! REQUIRED PAGES.
! INPUT:
! SIZE OF REQUEST.
! OUTPUT:
! ADDRESS OF 1ST WORD
GLOBAL ROUTINE GMEM ( SIZE ) =
BEGIN
ARGUMENT (SIZE,VALUE);
REGISTER
BLTAC; ! TEMPORARY REGISTER
LOCAL
AHOLE,
PAGEFULL,
BHOLE,
ANSWER,
PAGENUM,
PAGEADR,
FREEPAGE;
MAP
AHOLE: POINTER,
BHOLE: POINTER,
ANSWER: POINTER;
MAP
PAGEADR: POINTER;
TRACE ( 'GMEM' );
IF ( .SIZE GTR PAGESIZE ) OR ( .SIZE LEQ 0 )
THEN RMSBUG ( MSGINPUT ); ! BAD CORE REQUEST
PAGENUM = ZERO; ! POINTER TO PAGTAB
%([CODE TO UTILIZE OTS'S MEMORY MANAGER INSTEAD OF THIS. ])%
IF (RMS$$G LSS %O'643000')
THEN
BEGIN %(WE ARE LOADED BELOW 600000 FOR LIBOL)%
IF (ANSWER = $CALL (FGMEM, .SIZE)) IS FALSE
THEN
RMSBUG ( MSGCORE )
ELSE
RETURN .ANSWER
END;
%([END OF CODE TO UTILIZE OTS'S MEMORY MANAGER ])%
%([ LOOK AT THE INPUT ARGUMENTS ])%
LOOKAT (' CHUNK REQUESTED: ', SIZE );
%([ LOOP OVER ALL CHUNKS ])%
WHILE ( .PAGTAB [ .PAGENUM, BIGHOL ] LSS .SIZE )
AND
( .PAGENUM LEQ .NUMFREEPAGES )
DO INC ( PAGENUM, 1 ) ; ! BUMP POINTER
%([ DID WE FIND A CHUNK? IF NOT, WE MUST ALLOCATE A NEW PAGE ])%
IF .PAGENUM GTR .NUMFREEPAGES THEN ! NO HOLES FOUND
BEGIN
IF ( PAGENUM = CALLGPAGE ( PCI( 1 ) ) ) IS FALSE
THEN BADRETURN; ! GET A FREE PAGE
PAGEADR = ( .PAGENUM ^ P2W ) + OFSETMASK; ! GET LAST WORD IN PAGE
PAGENUM = .PAGENUM - .FRECOR; ! FIND OFFSET
PAGTAB [ .PAGENUM, BIGHOL ] = PAGESIZE; ! SET FREE SIZE
PAGTAB [ .PAGENUM, FIRSTFREE ] = .PAGEADR;
PAGEADR [ HOLESIZE ] = PAGESIZE; ! HOLE IS 512 LONG
PAGEADR [ FREEPTR ] = ZERO ! NO NEXT HOLE
END;
%( "PAGENUM" NOW CONTAINS THE PAGTAB INDEX OF THE
1ST PAGE WE FOUND WITH BIGHOL > SIZE )%
FREEPAGE = .PAGENUM + .FRECOR; ! FIND PAGE #
AHOLE = .PAGTAB [ .PAGENUM, FIRSTFREE ]; ! SET 1ST HOLE
BHOLE = ZERO;
WHILE .AHOLE [ HOLESIZE ] LSS .SIZE
DO
BEGIN
IF ( .AHOLE [ FREEPTR ] ^ W2P ISNT .FREEPAGE )
OR
!** [14] ROUTINE:GMEM, AT LINE 4478, EGM, 6-JUL-78
%([14])% ( ( .AHOLE - .AHOLE [ HOLESIZE ] + 1 ) /512 ISNT .FREEPAGE )
THEN RMSBUG ( MSGLINK ); ! PAGE LINKS SCREWED UP
IF .AHOLE [ FREEPTR ] IS ZERO THEN
RMSBUG ( MSGCORE ); ! CANT GET CORE
BHOLE = .AHOLE;
AHOLE = .AHOLE [ FREEPTR ] ! ADVANCE TO NEXT HOLE
END;
PAGEFULL = FALSE;
ANSWER = .AHOLE - .AHOLE [HOLESIZE ] +1; !ADDR OF HOLE
LOOKAT (' CHUNK ALLOCATED: ', ANSWER );
%([ IS IT AN EXACT MATCH? ])%
IF .AHOLE [ HOLESIZE ] IS .SIZE THEN ! EXACT MATCH
BEGIN
IF .BHOLE IS ZERO THEN ! 1ST HOLE IN PAGE...
BEGIN
PAGTAB [ .PAGENUM, FIRSTFREE ] = .AHOLE [ FREEPTR ];
IF .AHOLE [ FREEPTR ] IS ZERO THEN ! THE PAGE IS COMPLETELY FULL
PAGEFULL = TRUE
END
ELSE BHOLE [ FREEPTR ] = .AHOLE [ FREEPTR ]; ! RESET POINTER TO NEXT HOLE
END
ELSE %( IF AHOLE [ HOLESIZE ] GTR SIZE )%
BEGIN
AHOLE [ HOLESIZE ] = .AHOLE [ HOLESIZE ] - .SIZE ! NEW SIZE
END; %( OF IF AHOLE [ HOLESIZE ] GTR .SIZE )%
%( WE HAVE NOW SET UP THE ANSWER AND WE'RE READY TO RESET BIGHOL )%
IF .PAGEFULL %( IS TRUE )% THEN
PAGTAB [ .PAGENUM, BIGHOL ] = ZERO ! CLEAR BIGHOL
ELSE
BEGIN
AHOLE = .PAGTAB [ .PAGENUM, FIRSTFREE ]; ! START AT BEGINNING OF LIST
BHOLE = .AHOLE [ HOLESIZE ]; ! BHOLE = LARGEST SIZE FOUND SO FAR
UNTIL .AHOLE IS ZERO
DO
BEGIN
IF .AHOLE [ HOLESIZE ] GTR .BHOLE
THEN BHOLE = .AHOLE [ HOLESIZE ]; ! RESET BHOLE IS WE FOUND A BIGGER HOLE
AHOLE = .AHOLE [ FREEPTR ]
END;
PAGTAB [ .PAGENUM, BIGHOL ] = .BHOLE ! RESET IT
END;
%([ WE MUST NOW CLEAR THE CONTENTS OF THIS CORE BLOCK ])%
CLEAR ( .ANSWER, .SIZE );
%( ONE LAST CHECK )%
IF .ANSWER^ W2P ISNT ( .PAGENUM + .FRECOR ) THEN
RMSBUG ( MSGBSTATUS ); ! ANSWER ISNT RIGHT
RETURN .ANSWER
END;
! PMEM
! ====
! THIS ROUTINE DEALLOCATES STORAGE ON A PAGE. THE
! PAGE DIDN'T HAVE TO BE ALLOCATED BY GMEM,
! BUT IT MUST NOT CURRENTLY BE AVAILABLE.
! INPUT:
! ADDRESS OF CHUNK
! # OF CONTIGUOUS WORDS ( MUST NOT SPAN PAGE )
GLOBAL ROUTINE PMEM ( SIZE, CHUNK2 ) =
BEGIN
ARGUMENT (SIZE,VALUE);
ARGUMENT (CHUNK2,REFERENCE);
LOCAL
PAGENUM,
APAGE,
AHOLE,
CHUNK,
BHOLE;
MAP
CHUNK: POINTER,
AHOLE: POINTER;
TRACE ( 'PMEM');
CHUNK = .CHUNK2; ! GET ADDRESS OF CORE
%([code to utilize OTS's memory manager. ])%
%([ Calls on the module RMSOTS.MAC ])%
IF (RMS$$G LSS %O'643000')
THEN
BEGIN %(RMS IS LOADED BELOW 600000 FOR COBOL V12B)%
IF $CALL (FPMEM, .CHUNK, .SIZE )
THEN
GOODRETURN
ELSE
RMSBUG ( MSGINPUT )
END;
%([ End of code to utilize OTS's memory manager ])%
%([ CHECK OUT OUR ARGS ])%
LOOKAT (' CHUNK RETURNED: ', CHUNK );
LOOKAT (' CHUNK SIZE: ', SIZE );
APAGE = .CHUNK ^ W2P; ! GET PAGE #
PAGENUM = .APAGE - .FRECOR; ! AND OFFSET
IF ( .PAGENUM LSS ZERO )
OR
( .PAGENUM GTR .NUMFREEPAGES )
OR
( .SIZE GTR PAGESIZE ) OR ( .SIZE LEQ 0 )
THEN RMSBUG ( MSGINPUT );
IF ( .CHUNK + .SIZE -1 ) GTR ( .CHUNK OR %O'777' )
THEN RMSBUG ( MSGBSP ); ! CORE BLOCK SPANS PAGES
IF .PAGTAB [ .PAGENUM, FCMBUSY ] IS OFF
THEN RMSBUG ( MSGPNA ); ! PAGE NOT ALLOCATED
%([ CLEAR THE HEADER WORD OF EACH CHUNK SO IT WONT BE ACCIDENTLY
TAKEN TO BE A VALID CONTROL BLOCK ])%
CHUNK [ WHOLEWORD ] = ZERO;
CHUNK = .CHUNK + .SIZE -1; ! COMPUTE LAST WORD OF HOLE
%([ CHECK TO SEE IF THE PAGE IS FULL OF ALLOCATED HOLES ])%
IF ( AHOLE = .PAGTAB [ .PAGENUM, FIRSTFREE ] ) IS ZERO ! IF PAGE IS FULL
THEN
BEGIN
IF .PAGTAB [ .PAGENUM, BIGHOL ] ISNT ZERO
THEN RMSBUG ( MSGPM2 ); ! BIGHOL NON-ZERO
CHUNK [ HOLESIZE ] = .SIZE; ! SET CHUNK SIZE
CHUNK [ FREEPTR ] = ZERO; ! END OF CHAIN
PAGTAB [ .PAGENUM, FIRSTFREE ] = .CHUNK;
END
ELSE
BEGIN %( IF PAGE ISNT FULL )%
%([ IS THIS CHUNK LOWER ON THE PAGE THAN THE FIRST HOLE? ])%
IF .AHOLE LSS .CHUNK
THEN
BEGIN %( IF NEW CHUNK IS LOWER ON PAGE THEN 1ST HOLE)%
CHUNK [ HOLESIZE ] = .SIZE; ! SET SIZE
CHUNK [ FREEPTR ] = .AHOLE; ! RESET PTR
PAGTAB [ .PAGENUM, FIRSTFREE ] = .CHUNK
END
ELSE
BEGIN %( IF WE MUST SEARCH FREE-LIST )%
%([ LOOP OVER ALL CHUNKS UNTIL WE FIND IT ])%
WHILE .AHOLE [ FREEPTR ] GTR .CHUNK ! UNTIL WE COME TO OUR CHUNK...
DO BEGIN
IF .AHOLE [ FREEPTR ] IS ZERO THEN ! CHECK FOR INCONSISTENCIES
RMSBUG ( MSGPM3 ); ! BAD VALUE
IF .AHOLE [ FREEPTR ] LSS ( ( .APAGE ^ 9 ) )
THEN RMSBUG ( MSGLINK ); ! LINK INCONSISTENCY
AHOLE = .AHOLE [ FREEPTR ] ! AND GO TO NEXT HOLE
END;
%( AT THIS POINT, AHOLE POINTS TO THE HOLE WHICH
IS IMMEDIATELY LOWER ON THE PAGE THAN
CHUNK. )%
CHUNK [ FREEPTR ] = .AHOLE [ FREEPTR ] ; ! TAKE HIS LINK
AHOLE [ FREEPTR ] = .CHUNK; ! MAKE HIM POINT TO US
CHUNK [ HOLESIZE ] = .SIZE; ! SET OUT SIZE FIELD
%( NOW, COLLAPSE CHUNK IF IT TOUCHES NEXT HIGHER HOLE )%
IF .AHOLE - .AHOLE [ HOLESIZE ] IS .CHUNK
THEN
BEGIN %( TO MERGE OUR CHUNK WITH THE NEXT ONE DOWN IN THE PAGE )%
AHOLE [ HOLESIZE ] = .AHOLE [ HOLESIZE ] + .CHUNK [ HOLESIZE ];
AHOLE [ FREEPTR ] = .CHUNK [ FREEPTR ]; ! RELINK
CHUNK = .AHOLE
END %( OF MERGING WITH PREVIOUS HOLE )%
END; %( BEGIN SEARCHING FREE LIST )%
%( NOW, WE MUST CHECK IF WE SHOULD
MERGE THIS HOLE WITH THE PRECEDING HOLE ( THAT IS, THE
HOLE IMMEDIATELY ABOVE IT ON THE PAGE ) )%
IF ( .CHUNK - .CHUNK [ HOLESIZE ] ) IS .CHUNK [ FREEPTR ] ! IF THE HOLES TOUCH...
THEN
BEGIN %( TO MERGE THEM )%
AHOLE = .CHUNK [ FREEPTR ];
CHUNK [ HOLESIZE ] = .CHUNK [ HOLESIZE ] + .AHOLE [ HOLESIZE ]; ! MERGE SIZES
CHUNK [ FREEPTR ] = .AHOLE [ FREEPTR ]
END %( OF MERGE WITH PRECEDING CHUNK )%
END; %( OF ELSE IF PAGE WASNT FULL )%
IF .CHUNK [ HOLESIZE ] GTR .PAGTAB [ .PAGENUM, BIGHOL ]
THEN PAGTAB [ .PAGENUM, BIGHOL ] = .CHUNK [ HOLESIZE ]; ! UPDATE BIGHOL
%([ IS THIS THE LAST CHUNK TO BE RETURNED ON THIS PAGE? ])%
IF .PAGTAB [ .PAGENUM, BIGHOL ] IS PAGESIZE THEN
BEGIN %( TO GIVE BACK A COMPLETE PAGE )%
CALLPPAGE ( LCI ( APAGE ) , PCI ( 1 ), PCI ( TRUE ) )
END; %( OF IF BIGHOL IS PAGESIZE )%
GOODRETURN
END; %( OF PMEM ROUTINE )%
end
eludom