Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93d-bb - 7,6/ap016/qsrmem.x16
There are 2 other files named qsrmem.x16 in the archive. Click here to see a list.
	TITLE	QSRMEM -- Memory Manager for QUASAR

;
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1975,1976,1977,1978,1979,
;1980,1981,1982,1983,1984,1985,1986,1987.  ALL RIGHTS RESERVED.
;
;     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

	%%.QSR==:%%.QSR
	QSRVRS==:QSRVRS


;	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, AP = EXTENSION SIZE (QH.VAR QUEUE ONLY)
;	PUSHJ	P,M$GFRE
;	  RETURNS AP = CELL ADDRESS

M$GFRE:	LOAD	S1,.QHPAG(H),QH.SIZ	;GET THIS QUEUE'S SIZE
	MOVX	S2,QH.VAR		;VARIABLE QUEUE BIT
	TDNE	S2,.QHTYP(H)		;IS IT?
	ADD	S1,AP			;YES, INCLUDE EXTENSION SIZE
	PUSHJ	P,M%GMEM		;ALLOCATE THE SPACE
	MOVX	S1,QH.VAR		;VARIABLE QUEUE BIT
	TDNE	S1,.QHTYP(H)		;IS IT?
	STORE	AP,.QEVSZ(S2),QE.VSZ	;YES, SAVE EXTENSION SIZE FOR M$PFRE
	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:	LOAD	S1,.QHPAG(H),QH.SIZ	;GET THIS QUEUE'S SIZE
	MOVX	S2,QH.VAR		;VARIABLE QUEUE FLAG
	TDNN	S2,.QHTYP(H)		;IS IT?
	TDZA	S2,S2			;NO, EXTENSION SIZE = 0
	LOAD	S2,.QEVSZ(AP),QE.VSZ	;YES, GET EXTENSION SIZE
	ADD	S1,S2			;UPDATE TO TOTAL LENGTH
	MOVE	S2,AP			;COPY CELL ADDRESS
	PJRST	M%RMEM			;EXIT, RETURNING 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
	MOVE	S2,.QHTYP(S1)		;GET OLD QUEUE FLAGS
	XOR	S2,.QHTYP(H)		;SEE IF SAME AS NEW QUEUE FLAGS
	TXNE	S2,QH.VAR		;CHANGING STATE OF VARIABLE FLAG?
	STOPCD	(MDV,HALT,,<Moving different variabilities>)
	PUSH	P,S1			;SAVE NEW HEADER
	PUSHJ	P,M$DLNK		;REMOVE CELL FROM OLD QUEUE
	LOAD	P1,.QHPAG(H),QH.SIZ	;GET THIS QUEUE'S SIZE
	POP	P,H			;NEW HEADER
	LOAD	S1,.QHPAG(H),QH.SIZ	;GET THIS QUEUE'S SIZE
	CAME	S1,P1			;MOVING DIFFERENT SIZES
	STOPCD	(MDS,HALT,,<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
;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