.SBTTL QUEING - message and chunk queuing routines ; 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) 1982,1981,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 ; 4(002) 07-APR-81 RLS Changes to reflect use of message header chunk for data VQUENG=002 VEDIT=VEDIT+VQUENG .SBTTL QUEMSG - 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 QUEMSG: TRACE TRCQUE,<(SP),R0,R1,R5> CALL FMSGI ;init full message for data extraction SAVE R2 PIOFF ;protect rest from interrupts INC TCMSG3(R1) ;one more message on its queue 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 R0,MSGNXT(R2) ;store forward pointer, too CLR MSGNXT(R0) ;last forward pointer is null PION ;allow interrupts now BR 17$ ; 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 PION ;allow interrupts now SIGNAL R1,EBQMSG ;maybe, restart it. ; here to return, restoring r2. 17$: RESTOR R2 RETURN .SBTTL DEQMSG - 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: TRACE TRCQUE,<(SP),R5> MOV TCMSG1(R5),R0 ;any messages? BEQ DEQEMP ;no. DEQMS1: SAVE R1 ;dq a message PIOFF ;protect rest from interrupts DEC TCMSG3(R5) ;one fewer message on queue MOV MSGNXT(R0),R1 ;get pointer to following message MOV R1,TCMSG1(R5) ;make it the first BNE 13$ ;branch if not last msg CLR TCMSG2(R5) ;clear pointer to last message 13$: PION ;allow interrupts now RESTOR R1 ;done with r1 TRACE TRCQUE,R0 ;trace message obtained CLC ;clear c to flag success RETURN ;return, r0 = message (0 if none) ; here if no message 15$: DEQEMP: TRACE TRCQUE,R0 ;trace no messages available SEC ;set c to flag no message RETURN .SBTTL DEQMID - 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 ; C set -- no message with specified id DEQMID: TRACE TRCQUE,<(SP),R5,R1> MOV TCMSG1(R5),R0 ;any messages? BEQ DEQEMP ;no, use deqmsg to give unsuccessful return. CMP R1,MSGID(R0) ;yes, does first msg have right id? BEQ DEQMS1 ;yes, use deqmsg to get first msg SAVE R2 PIOFF ;protect rest from interrupts 11$: MOV R0,R2 ;make current chunk ptr into previous MOV MSGNXT(R2),R0 ;get next chunk BEQ 16$ ;end of list => no match CMP R1,MSGID(R0) ;there is one, check for id match BNE 11$ ;no, check the rest of the messages. ; here when we have a match. ;R0/ptr to current chunk ;R2/ptr to previous chunk DEC TCMSG3(R5) ;decrement queue counter MOV MSGNXT(R0),MSGNXT(R2) ;link around current message BNE 14$ MOV R2,TCMSG2(R5) ;previous message is now last one 14$: PION ;allow interrupts now RESTOR R2 TRACE TRCQUE,R0 ;trace success in deqmid CLC ;indicate success RETURN ; here if there is no match but there is at least one message. 16$: PION ;allow interrupts now TRACE TRCQUE,R0 ;trace unsuccessful return RESTOR R2 SEC ;flag nothing there RETURN .SBTTL QUECHK - 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: TRACE TRCQUE,<(SP),R0,R1,R5> PIOFF ;need peace and quiet for awhile MOV R0,@TCCHK2(R1) ;link end of queue to new chunk MOV R0,TCCHK2(R1) ;new chunk is last CLR (R0) ;guarantee that this chunk is the end PION ;allow interrupts now SIGNAL R1,EBQCHK ;maybe, if so wake him. RETURN QUEFST: ;fast chunk queuer - called with interrupts off MOV R0,@TCCHK2(R1) ;link end of queue to new chunk MOV R0,TCCHK2(R1) ;new chunk is last CLR (R0) ;guarantee that this chunk is the end SIGNAL R1,EBQCHK,NOTRACE ;maybe, if so wake him. RETURN .SBTTL DEQCHK - 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: PIOFF ;protect rest from interrupts MOV TCCHKQ(R5),R0 ;pick up chunk list BEQ 18$ ;there are none. return a 0. MOV (R0),TCCHKQ(R5) ;delink this chunk BNE 16$ MOV R5,TCCHK2(R5) ;queue empty - set tail ptr properly ADD #TCCHKQ,TCCHK2(R5) ;pt to head 16$: CLR (R0) ;remove link from this chunk PION ;allow interrupts now TRACE TRCQUE,<(SP),R0,R5>;trace success exit CLC ;clear c to flag success RETURN ; here to return unsuccessfully ; ...don't bother to trace since it's the normal condition 18$: PION ;allow interrupts now SEC ;set c to flag no chunks RETURN