Trailing-Edge
-
PDP-10 Archives
-
BB-5255D-BM
-
language-sources/qsrmem.mac
There are 28 other files named qsrmem.mac in the archive. Click here to see a list.
TITLE QSRMEM -- Memory Manager for QUASAR
;
;
; COPYRIGHT (c) 1975,1976,1977,1978,1979
; DIGITAL EQUIPMENT CORPORATION
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
; AND 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. NO TITLE TO
; AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE
; WITHOUT NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
; BY DIGITAL EQUIPMENT CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY
; DIGITAL.
SEARCH QSRMAC,GLXMAC ;PARAMETER FILE
PROLOGUE(QSRMEM) ;GENERATE THE NECESSARY SYMBOLS
; Entry points found in QSRMEM
INTERN M$GFRE ;;Get a cell from the free list for queue 'H'
INTERN M$PFRE ;Put cell 'AP' back on the free list for queue 'H'
INTERN M$RFRE ;Remove cell 'AP' from the queue 'H' and return it to the free list
INTERN M$DLNK ;Remove cell 'AP' from the queue 'H'
INTERN M$LINK ;Link cell 'AP' into the queue 'H' before entry 'E'
INTERN M$ELNK ;Link cell 'AP' at the end of the queue 'H'
INTERN M$FLNK ;Link cell 'AP' at the front of the queue 'H'
INTERN M$MOVE ;Move cell 'AP' from queue 'H' to queue 'S1'
SUBTTL Free Space Management Subroutines
;ROUTINE TO GET A FREE CELL FOR A QUEUE
;CALL H = QUEUE HEADER POINTER
; PUSHJ P,M$GFRE
; RETURNS AP = CELL ADDRESS
M$GFRE: PUSHJ P,SETSIZ ;SET SIZE FOR THIS QUEUE
PUSHJ P,M%GMEM ;ALLOCATE THE SPACE
MOVE AP,S2 ;RETURN ADDRESS IN AP
$RETT ;AND RETURN
;ROUTINES TO RETURN A CELL TO THE CORRECT FREE LIST
;CALL AP = CELL ADDRESS (MAY BE DESTROYED)
; H = QUEUE HEADER POINTER
; PUSHJ P,M$PFRE (M$RFRE IF ENTRY MUST BE DE-LINKED)
M$RFRE: PUSHJ P,M$DLNK ;DE-LINK THIS ENTRY BEFORE RETURNING IT
M$PFRE: PUSHJ P,SETSIZ ;SET SIZE FOR THIS QUEUE
MOVE S2,AP ;COPY CELL ADDRESS
PJRST M%RMEM ;EXIT, RETURNNING MEMORY
;ROUTINE TO MOVE A CELL FROM ONE QUEUE TO ANOTHER (PROCESSING TO USE, ETC..)
;CALL H = CURRENT QUEUE
; AP = THE CELL TO MOVE
; S1 = NEW QUEUE
; PUSHJ P,M$MOVE
;RETURNS AP & H UPDATED TO REFLECT NEW CELL
M$MOVE: PUSHJ P,.SAVE1 ;SAVE P1 FIRST
PUSH P,S1 ;SAVE NEW HEADER
PUSHJ P,M$DLNK ;REMOVE CELL FROM OLD QUEUE
PUSHJ P,SETSIZ ;DETERMINE SIZE OF OLD QUEUE
MOVE P1,S1 ;SAVE SIZE OF OLD QUEUE
POP P,H ;NEW HEADER
PUSHJ P,SETSIZ ;FIND SIZE OF THIS ONE
CAME S1,P1 ;MOVING DIFFERENT SIZES
$STOP(MDS,MOVING DIFFERENT SIZES)
LOAD S1,.QHPAG(H),QH.SCH ;BASE SCHEDULER VECTOR FOR NEW QUEUE
JUMPE S1,M$ELNK ;IF NO VECTOR TACK IT TO THE END
PJRST SCHLNK(S1) ;LINK IT IN AND RETURN
;SUBROUTINE TO RETURN SIZE OF QUEUE "H" IN S1, WIPES S2
SETSIZ: LOAD S1,.QHPAG(H),QH.SIZ ;GET SIZE OF QUEUE ENTRY
LOAD S2,.QHTYP(H),QH.IPC ;GET IPCF BIT FROM QUEUE TYPE
JUMPE S2,.RETT ;NO,,RETURN
MOVEI S2,SPL.SZ ;GET THE SPOOL SIZE
CAMGE S2,G$MPS## ;IS IT LARGER THEN MAX IPCF PACKET SIZE ?
MOVE S2,G$MPS## ;NO,,USE PACKET SIZE
ADD S1,S2 ;GET QUEUE LENGTH
$RETT ;RETURN
;ROUTINES TO LINK AN ENTRY INTO A QUEUE
;CALL AP = ENTRY TO LINK
; H = QUEUE HEADER POINTER
; E = SUCCESSOR OF THIS ENTRY (FOR ORDERING IF CALLING M$LINK)
; PUSHJ P,M$xxxx
; WHERE xxxx IS
; 'LINK' TO LINK ENTRY BEFORE 'E'
; 'ELNK' TO LINK AT THE END OF THE QUEUE
; 'FLNK' TO LINK AT THE BEGINNING OF THE QUEUE
M$ELNK: LOAD S1,.QHLNK(H),QH.PTL ;FIND THE LAST
STORE AP,.QHLNK(H),QH.PTL ;THIS IS NOW THE LAST
STORE S1,.QELNK(AP),QE.PTP ;POINT BACK AT THE OLD LAST
ZERO .QELNK(AP),QE.PTN ;LAST HAS NO NEXT
JUMPE S1,ELNK.1 ;JUMP IF THIS IS THE FIRST
STORE AP,.QELNK(S1),QE.PTN ;LINK THE OLD LAST TO THIS ONE
$RETT ;AND RETURN
ELNK.1: STORE AP,.QHLNK(H),QH.PTF ;STORE AS FIRST IN QUEUE ALSO
$RETT ;AND RETURN
M$FLNK: LOAD S1,.QHLNK(H),QH.PTF ;FIND THE FIRST
STORE AP,.QHLNK(H),QH.PTF ;THIS IS NOW THE FIRST
STORE S1,.QELNK(AP),QE.PTN ;POINT TO THE OLD FIRST
ZERO .QELNK(AP),QE.PTP ;FIRST HAS NO PREVIOUS
JUMPE S1,FLNK.1 ;JUMP IF THIS IS THE LAST
STORE AP,.QELNK(S1),QE.PTP ;LINK THE OLD FIRST BACK TO THIS
$RETT ;AND RETURN
FLNK.1: STORE AP,.QHLNK(H),QH.PTL ;STORE THIS AS LAST IN QUEUE ALSO
$RETT ;AND RETURN
M$LINK: JUMPE E,M$ELNK ;USE THE SPECIAL CASE IF THIS IS TO BE THE LAST
LOAD S1,.QELNK(E),QE.PTP ;LOAD SUCCESSORS PREVIOUS
JUMPE S1,M$FLNK ;JUMP IF THIS IS TO BE THE FIRST
STORE S1,.QELNK(AP),QE.PTP ;THAT IS MY PREVIOUS
STORE AP,.QELNK(S1),QE.PTN ;AND I AM ITS NEXT
STORE E,.QELNK(AP),QE.PTN ;POINT TO THE SUCESSOR
STORE AP,.QELNK(E),QE.PTP ;I AM ITS PREVIOUS
$RETT ;AND RETURN
;ROUTINE TO DISSOLVE THE LINKS OF AN ENTRY
;NORMALLY CALLED BEFORE THE CALL TO M$PFRE AND IS CALLED BY M$RFRE
;CALL AP = CELL TO REMOVE
; H = QUEUE HEADER POINTER
; PUSHJ P,M$DLNK
M$DLNK: LOAD S1,.QELNK(AP),QE.PTP ;GET LINKS OF THE ENTRY TO BE REMOVED
LOAD S2,.QELNK(AP),QE.PTN ;S1 = PREVIOUS, S2 = SUCCESSOR
JUMPE S1,DLNK.1 ;JUMP IF REMOVING THE FIRST
JUMPE S2,DLNK.3 ;JUMP IF REMOVING THE LAST
STORE S1,.QELNK(S2),QE.PTP ;LINK THE REMAINING ENTRIES TOGETHER
STORE S2,.QELNK(S1),QE.PTN ;TO COMPLETELY DISSOLVE THE OLD LINKS
$RETT ;AND RETURN
DLNK.1: JUMPE S2,DLNK.2 ;JUMP IF REMOVING THE ONLY
STORE S2,.QHLNK(H),QH.PTF ;STORE SUCCESSOR AS THE NEW FIRST
ZERO .QELNK(S2),QE.PTP ;AND CLEAR ITS BACKWARD LINK
$RETT ;AND RETURN
DLNK.2: ZERO .QHLNK(H) ;IF REMOVING THE ONLY, CLEAR THE HEADER
$RETT ;AND RETURN
DLNK.3: STORE S1,.QHLNK(H),QH.PTL ;STORE PREVIOUS AS NEW LAST
ZERO .QELNK(S1),QE.PTN ;AND CLEAR ITS FORWARD LINK
$RETT ;AND RETURN
END