Google
 

Trailing-Edge - PDP-10 Archives - BB-D351B-SM - sources/queing.p11
There are 8 other files named queing.p11 in the archive. Click here to see a list.
.SBTTL	QUEUEING SUBROUTINES
;
; THIS SECTION CONTAINS THE SUBROUTINES WHICH SEND MESSAGES
;  AND CHUNKS TO ANOTHER TASK, AND SUBROUTINES WHICH
;  RETRIEVE MESSAGES AND CHUNKS SENT TO THE
;  CURRENT TASK.
;
.REPT 0


                          COPYRIGHT (c) 1980, 1979
            DIGITAL EQUIPMENT CORPORATION, maynard, mass.

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.

.ENDR
;
;
;
;
;		REVISION HISTORY
;
;
; 4(001) BS	ADDED EDIT NUMBERS
;
;
;
VQUENG=001
;
VEDIT=VEDIT+VQUENG
;
;
;
; APPEND A MESSAGE TO A LIST OF MESSAGES
;
; R0 = POINTER TO THE MESSAGE TO BE ADDED TO A LIST
; R1 = POINTER TO THE TCB THAT OWNS THE LIST TO BE APPENDED
;	TO.
;
QUEMSG:	MOV	R2,-(SP)	;SAVE R2
.IF NE,DEBUG
	CMP	R0,#FIRZER	;IS MESSAGE IN FREE SPACE?
	BHIS	11$		;YES.
	STOPCD	DBG		;NO, INVALID MESSAGE PARM.
11$:
.IF NE,CHOWNR
	BIT	#37,R0		;ON A CHUNK BOUNDRY?
	BEQ	12$		;YES.
	STOPCD	DBG		;NO, INVALID MESSAGE
12$:
.ENDC ;.IF NE,CHOWNR
	BIT	#1,(R0)		;IS FIRST CHUNK FREE?
	BEQ	13$		;NO.
	STOPCD	DBG		;YES, THIS SHOULD NOT HAPPEN!
13$:	TST	MSGQUE(R0)	;HAS THIS MESSAGE A HISTORY?
	BEQ	14$		;NO.
	BIT	#1,MSGQUE(R0)	;YES, IS IT ON ANOTHER QUEUE?
	BNE	14$		;NO.
	STOPCD	DBG		;YES, THAT IS WRONG.
14$:	MOV	R1,MSGQUE(R0)	;NO, STORE NAME OF NEW OWNING TASK
	INC	TCMSG3(R1)	;ONE MORE MESSAGE ON ITS QUEUE
.ENDC ;.IF NE,DEBUG
	MOV	TCMSG2(R1),R2	;ANY MESSAGES IN THE LIST?
	BEQ	15$		;NO.  THIS IS THE FIRST.
	MOV	R0,TCMSG2(R1)	;YES, THIS MESSAGE IS LAST
	MOV	R2,MSGPRV(R0)	;OLD LAST NOW NEXT-TO-LAST
	MOV	R0,MSGNXT(R2)	;STORE FORWARD POINTER, TOO
	CLR	MSGNXT(R0)	;LAST FORWARD POINTER IS NULL
	BR	17$		;RESTORE R2 AND RETURN.
;
;
; HERE IF THIS IS THE FIRST MESSAGE
;
15$:	MOV	R0,TCMSG1(R1)	;STORE AS FIRST MESSAGE
	MOV	R0,TCMSG2(R1)	; AND AS LAST.
	CLR	MSGNXT(R0)	;FORWARD POINTER IS NULL
	CLR	MSGPRV(R0)	;AS IS BACKWARD POINTER.
	BIT	#EBQMSG,(R1)	;IS TASK WAITING FOR A MESSAGE?
	BEQ	16$		;NO.
	BIC	#EBQMSG!EBWAIT,(R1) ;MAYBE, RESTART IT.
16$:
;
;  HERE TO RETURN, RESTORING R2.
;
17$:	MOV	(SP)+,R2	;RESTORE R2
	TRACE	TRCQUE,R0	;TRACE MESSAGE SENT
	RTS	PC		; AND RETURN.
;
;
; REMOVE THE LATEST MESSAGE FROM A LIST OF MESSAGES
;
; R5 = POINTER TO THE TCB OWNING THE LIST
;
; ON RETURN:
;
; R0 = POINTER TO THE MESSAGE REMOVED FROM THE LIST.
;	(0 MEANS NO MORE MESSAGES)
;
;  C IS CLEAR IF WE GOT A MESSAGE, SET OTHERWISE.
;
DEQMSG:	MOV	TCMSG1(R5),R0	;ANY MESSAGES?
	BEQ	15$		;NO.
	MOV	R1,-(SP)	;YES, SAVE R1
.IF NE,DEBUG
	CMP	R5,MSGQUE(R0)	;IS THIS TASK THE INTENDED OWNER?
	BEQ	11$		;YES.
	STOPCD	DBG		;NO, SOMETHING IS WRONG!
11$:	BIS	#1,MSGQUE(R0)	;YES, FLAG MESSAGE NOT ON QUEUE
	DEC	TCMSG3(R5)	;ONE FEWER MESSAGE ON QUEUE
	BGE	12$		;COUNTER IS .GE. 0
	STOPCD	DBG		;COUNTER IS MESSED UP!
12$:
.ENDC ;.IF NE,DEBUG
	MOV	MSGNXT(R0),R1	;GET POINTER TO FOLLOWING MESSAGE
	MOV	R1,TCMSG1(R5)	;MAKE IT THE FIRST
	BEQ	14$		;BRANCH IF JUST GOT LAST MSG
	CLR	MSGPRV(R1)	;CLEAR ITS BACK POINTER
13$:	MOV	(SP)+,R1	;DONE WITH R1
	TRACE	TRCQUE,R0	;TRACE MESSAGE OBTAINED
	CLC			;CLEAR C TO FLAG SUCCESS
	RTS	PC		;RETURN, R0 = MESSAGE (0 IF NONE)
;
; HERE IF WE JUST GOT THE LAST MESSAGE
;
14$:	CLR	TCMSG2(R5)	;CLEAR POINTER TO LAST MESSAGE
	BR	13$		; AND CONTINUE.
;
;
; HERE IF NO MESSAGE
;
15$:	TRACE	TRCQUE,R0	;TRACE NO MESSAGES AVAILABLE
.IF NE,DEBUG
	TST	TCMSG3(R5)	;DOES COUNTER AGREE?
	BEQ	16$		;YES.
	STOPCD	DBG		;NO, MESSAGES LOST FROM QUEUE
16$:
.ENDC ;.IF NE,DEBUG
	SEC			;SET C TO FLAG NO MESSAGE
	RTS	PC		;RETURN.
;
;
; SUBROUTINE TO GET THE LATEST MESSAGE WITH A SPECIFIED ID.
;
; R5 = POINTER TO THE TCB THAT OWNS THE LIST
; R1 = THE ID
;
; ON RETURN:
;
;	C CLEAR -- R0 = POINTER TO MESSAGE GOTTEN
;	C SET -- NO MESSAGE WITH SPECIFIED ID
;
DEQMID:	MOV	TCMSG1(R5),R0	;ANY MESSAGES?
	BEQ	DEQMSG		;NO, USE DEQMSG TO GIVE UNSUCCESSFUL RETURN.
	CMP	R1,MSGID(R0)	;YES, DOES FIRST MSG HAVE RIGHT ID?
	BEQ	DEQMSG		;YES, USE DEQMSG TO GET FIRST MSG
11$:	MOV	MSGNXT(R0),R0	;NO, IS THERE ANOTHER MESSAGE?
	BEQ	16$		;NO, NO MATCH.
	CMP	R1,MSGID(R0)	;YES, DOES IT MATCH?
	BNE	11$		;NO, CHECK THE REST OF THE MESSAGES.
;
; HERE WHEN WE HAVE A MATCH.
;
	MOV	R2,-(SP)	;SAVE R2
	MOV	R3,-(SP)	; AND R3
.IF NE,DEBUG
	CMP	R5,MSGQUE(R0)	;IS THIS TASK THE INTENDED OWNER?
	BEQ	12$		;YES.
	STOPCD	DBG		;NO, SOMETHING IS WRONG!
12$:	BIS	#1,MSGQUE(R0)	;YES, FLAG MESSAGE NOT ON QUEUE
	DEC	TCMSG3(R5)	;DECREMENT QUEUE COUNTER
	BGE	13$		; .GE. 0 IS OK
	STOPCD	DBG		;COUNTER IS MESSED UP
13$:
.ENDC ;.IF NE,DEBUG
	MOV	MSGPRV(R0),R3	;GET PREVIOUS MESSAGE (MUST BE ONE
				; SINCE FIRST MSG IS A SPECIAL CASE)
	MOV	MSGNXT(R0),R2	;GET NEXT MESSAGE, IF ANY.
	BEQ	15$		;THERE IS NO NEXT MESSAGE
	MOV	R3,MSGPRV(R2)	;POINT NEXT'S BACK POINTER AROUND US
14$:	MOV	R2,MSGNXT(R3)	;POINT PREV'S FORWARD POINTER AROUND US
	MOV	(SP)+,R3	;RESTORE R3
	MOV	(SP)+,R2	;RESTORE R2
	TRACE	TRCQUE,R0	;TRACE SUCCESS IN DEQMID
	CLC			;INDICATE SUCCESS
	RTS	PC		;RETURN.
;
;
; HERE IF WE ARE GETTING LAST MESSAGE.  POINT LAST
;  MESSAGE POINTER TO NEW LAST MESSAGE (THE MESSAGE JUST BEFORE
;  THIS ONE) AND DON'T STORE A BACK POINTER IN THE (NON-EXISTENT)
;  NEXT MESSAGE.
;
15$:	MOV	R3,TCMSG2(R5)	;NEW LAST MSG IS PREV MSG
	BR	14$		;DON'T STORE IN MSGPRV(R2).
;
; HERE IF THERE IS NO MATCH BUT THERE IS AT LEAST ONE MESSAGE.
;
16$:	TRACE	TRCQUE,R0	;TRACE UNSUCCESSFUL RETURN
.IF NE,DEBUG
	TST	TCMSG3(R5)	;DOES COUNT AGREE THERE ARE MSGS?
	BGT	17$		;YES.
	STOPCD	DBG		;NO, COUNT IS MESSED UP!
17$:
.ENDC ;.IF NE,DEBUG
	SEC			;FLAG NOTHING THERE
	RTS	PC		;RETURN.
;
;
; APPEND A CHUNK TO THE LIST OF CHUNKS OWNED BY A TASK.
;  THIS CODE RUNS AT INTERRUPT LEVEL SO THE POINTER IN THE
;  TASK CONTROL BLOCK IS TAKEN AS THE POINTER TO THE NEWEST
;  CHUNK.
;
; R1 = POINTER TO THE TCB TO BE GIVEN THE CHUNK
;
; R0 = POINTER TO THE CHUNK TO BE GIVEN.
;
QUECHK:
.IF NE,DEBUG
	CMP	TCCHK1(R1),R0	;IS THIS CHUNK ALREADY ON LIST?
	BNE	11$		;NO.
	STOPCD	DBG		;YES, QUEUEING ERROR.
11$:
.IF NE,CHOWNR
	BIT	#37,R0		;IS THIS REALLY A CHUNK?
	BEQ	12$		;YES.
	STOPCD	DBG		;NO, THERE IS A PROBLEM!
12$:
.ENDC ;.IF NE,CHOWNR
	BIT	#1,(R0)		;IS THIS CHUNK FREE?
	BEQ	13$		;NO.
	STOPCD	DBG		;YES, BETTER NOT BE!
13$:
.ENDC ;.IF NE,DEBUG
	MOV	TCCHK1(R1),(R0) ;STORE LINK POINTER IN CHUNK
	MOV	R0,TCCHK1(R1)	;STORE POINTER TO LIST IN TASK CONTROL BLOCK
	BIT	#EBQCHK,(R1)	;IS TASK WAITING FOR A CHUNK?
	BEQ	14$		;NO.
	BIC	#EBQCHK!EBWAIT,(R1) ;MAYBE, IF SO WAKE HIM.
14$:	TRACE	TRCQUE,R0	;TRACE SENDING A CHUNK
	RTS	PC		;RETURN.
;
;
; DEQUEUE A CHUNK FROM A TASK'S CHUNK LIST.  GET THE OLDEST ONE,
;  WHICH WILL BE LAST ON THE LIST.
;
; R5 = POINTER TO THE TCB OF THE TASK OWNING THE LIST.
;
; ON RETURN:
;
; R0 = POINTER TO THE OLDEST CHUNK, NOW REMOVED FROM THE
;  LIST.  0 RETURNED MEANS NO MORE CHUNKS.
;
;	C IS SET IF NO MORE CHUNKS, CLEAR OTHERWISE.
;
;
DEQCHK:	MOV	R1,-(SP)	;SAVE R1
11$:	MOV	TCCHK1(R5),R0	;PICK UP CHUNK LIST
	BEQ	18$		;THERE ARE NONE.  RETURN A 0.
	MOV	(R0),R1		;YES, IS THERE AN OLDER ONE?
	BEQ	15$		;NO.
12$:	TST	(R1)		;YES, IS THERE AN EVEN OLDER ONE?
	BEQ	13$		;NO.  THIS ONE IS OLDEST.
	MOV	(R1),R0		;YES, GET NEXT
	TST	(R0)		;IS IT OLDEST?
	BEQ	14$		;YES, USE IT.
	MOV	(R0),R1		;NO, GET NEXT
	BR	12$		; AND DO IT AGAIN.

13$:	CLR	(R0)		;CLEAR THE NEXT-TO-OLDEST'S POINTER
	MOV	R1,R0		;GET THE REGISTERS RIGHT
	BR	17$		;AND GO USE THIS CHUNK

14$:	CLR	(R1)		;CLEAR THE NEXT-TO-OLDEST'S POINTER
	BR	17$		;AND GO USE THIS CHUNK
;
;
; HERE IF THERE IS ONLY ONE CHUNK ON THE LIST.  WE HAVE TO
;  WORRY ABOUT INTERRUPT LEVEL INTERFERING WITH OUR REMOVING
;  IT.
;
15$:	MFPS	-(SP)		;SAVE CURRENT PRIORITY LEVEL
	MTPS	#BR7		;DISABLE INTERRUPTS
	CMP	R0,TCCHK1(R5)	;IS THIS CHUNK STILL FIRST?
	BEQ	16$		;YES.
	MTPS	(SP)+		;NO, ENABLE INTERRUPTS
	BR	11$		; AND DO IT ALL OVER AGAIN.
;
; HERE WHEN WE HAVE SUCCESSFULLY REMOVED THE FIRST CHUNK
;  FROM THE LIST.
;
16$:	CLR	TCCHK1(R5)	;LIST IS EMPTY
	MTPS	(SP)+		;RESTORE INTERRUPT LEVEL
17$:	MOV	(SP)+,R1	;RESTORE R1
	TRACE	TRCQUE,R0	;TRACE CHUNK OBTAINED SUCCESSFULLY
	CLC			;CLEAR C TO FLAG SUCCESS
	RTS	PC		;RETURN TO CALLER.
;
; HERE TO RETURN UNSUCCESSFULLY
;
18$:	MOV	(SP)+,R1	;RESTORE R1
	TRACE	TRCQUE,R0	;TRACE NO MORE CHUNKS CONDITION
	SEC			;SET C TO FLAG NO CHUNKS
	RTS	PC		;RETURN TO CALLER.
;