Trailing-Edge
-
PDP-10 Archives
-
AP-D471B-SB_1978
-
msgout.bli
There are no other files named msgout.bli in the archive.
!***COPYRIGHT (C) 1974, 1975, 1976, 1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
MODULE MSGOUT(RESERVE(#11,#12,#13,#14),SREG=#17,FREG=#16,DREGS=4,
VREG=#15,MLIST,TIMER=EXTERNAL(SIX12),FSAVE)=
BEGIN
REQUIRE DATA.BLI;
EXTERNAL ROLIN,
MOVE,
UNDEFER;
OWN OPCHAIN;
MACRO FIRST = OPCHAIN<RH>$,
LAST = OPCHAIN<LH>$;
COMMENT;
!ROUTINE GETALTERNATE
!======= ============
! THIS ROUTINE GETS THE ALTERNATE OF A TERMINAL
ROUTINE GETALTERNATE(SRCPTR)=
BEGIN
MAP FORMAT SRCPTR;
MACRO CURALT=(.SRCPTR[S0ALTPTR])<IF .SRCPTR[S0RIGHTALT] THEN RIGHT ELSE LEFT, HALFWORD >$;
IF .SRCPTR[S0SELF] THEN RETURN .SRCPTR;
.CURALT
END;
EXTERNAL DELGH,
DELMH,
DGPURGE,
UNLINK,
BUFAVAIL;
COMMENT;
! SUBROUTINE MSWRITE
! ========== =======
! LAST MODIFIED: 15 SEPT 76 BY CDO
ROUTINE MSWRITE(DEST) =
BEGIN
REGISTER
MHPTR,
GHPTR,
SRCPTR;
LOCAL SENDTO,
SAVEREST,
SAVECHNK,
UDX;
MAP FORMAT MHPTR;
MAP FORMAT GHPTR;
MAP FORMAT SRCPTR;
MAP FORMAT SENDTO;
SRCPTR _ .DEST; ! PICKUP THE SOURCE POINTER
IF ( GHPTR _ .SRCPTR[S0FIGHPTR] ) EQL 0 THEN RETURN; ! IF NO MESSAGES, RETURN
IF .GHPTR[G0SENDING] EQL 0 THEN ! IF OUTPUT NOT GOING ALREADY
BEGIN
IF .SRCPTR[S0ED] EQL DISABLED THEN RETURN; ! CHECK FOR DISABLED NOW
GHPTR[G0SENDING] _ 1 ! NOT, MARK OUTPUT IN PROGRESS
END;
IF ( SENDTO _ GETALTERNATE( .SRCPTR ) ) EQL 0 THEN RETURN; ! IF NO ONE TO SEND TO, RETURN
IF .SENDTO<RH> NEQ .SRCPTR<RH> THEN
IF .SENDTO[ S0IGHS ] NEQ 0 THEN RETURN; ! IF ALTERNATE IS OUTPUTTING, RETURN
IF (UDX_.SENDTO[S0PORTPTR]) EQL 0 THEN RETURN; ! IF NO PORT CONNECTED, RETURN
IF NOT BUFAVAIL(.UDX) THEN RETURN; ! IF NO OUTPUT BUFFERS AROUND, RETURN
IF (MHPTR _ .GHPTR[G0OUTMH]) EQL 0 THEN RETURN; ! IF NO MESSAGES AVB YET, RETURN
GHPTR[G0OUTMH] _ .MHPTR[M0FORE]; ! SET UP FOR NEXT TIME
IF .MHPTR[M0CHNKS] EQL 0 THEN ! IF NOT IN CORE
IF .MHPTR[M0DSKADDR] NEQ 0 THEN ! IF ON DISK
MHPTR[M0INCHNK]_MHPTR[M0OUTCHNK]_ROLIN(.MHPTR[M0DSKADDR],.GHPTR[G0DSKGHADDR])
ELSE
INFORM(PLIT ASCIZ 'FMESSAGE MARKED ON DISK BUT NO DISK ADDRESS@',
0,0,0,0,0);
! DECREMENT COUNT OF RECEIVERS AND IF = 0, CAN RELEASE THE MESSAGE
SAVEREST _ IF (MHPTR[M0DSCNT] _ .MHPTR[M0DSCNT] - 1) LEQ 0 THEN FALSE
ELSE TRUE;
SAVECHNK _ IF .SAVEREST AND .MHPTR[M0DSKADDR] EQL 0 THEN TRUE
ELSE FALSE;
OUTMSG(.MHPTR[M0OUTCHNK],.UDX,.SAVECHNK,FALSE); ! OUTPUT THE MESSAGE
IF NOT .SAVECHNK THEN MHPTR[M0CHNKS] _ 0; ! DONE BY OUTMSG
IF .GHPTR[G0ENDI] AND (.GHPTR[G0OUTMH] EQL 0) THEN ! IF THE GROUP IS DONE (I.E. EGI/EPI
! ENCOUNTERED AND COMPLETELY TRANSMITTED)
BEGIN
IF .GHPTR[G0ONDSK] THEN DGPURGE(.GHPTR[G0DSKGHADDR],.SAVEREST); ! CLEAR DISK IMAGE
IF NOT .SAVEREST THEN DELGH(SRCPTR[S0IGHS],.GHPTR) ! DELETE THE GROUP IF NO MORE DESTINATIONS
ELSE DELETE( SRCPTR[S0IGHS], .GHPTR, G0SIZE, NOTCHUNK); ! ELSE DELETE ONLY
! THE GROUP HEADER AND UNLINK
IF .SRCPTR[S0IGHS] EQL 0 AND .PIGGYBACK NEQ 0 AND NOT .SRCPTR[S0DEFSENDING] THEN
! IF THERE ARE NO MORE IMMEDIATE GROUPS
BEGIN ! AND THERE IS A PIGGY BACK QUOTA THEN
SRCPTR[S0DEFSENDING] _ TRUE; ! SET A FLAG SO WE DON'T TRY TO UNDEFER
UNDEFER( .SRCPTR, .PIGGYBACK) ! TRY TO UNDEFER SOME
! ANY MORE UNTIL THE USER DOES ANOTHER
! IMMEDIATE SEND
END
END;
0
END;
COMMENT;
! MSGCHN INSERTS A TERMINAL INTO THE OUTPUT CHAIN. MSGOUT TAKES CARE OF THE REMOVAL
GLOBAL ROUTINE MSGCHN(DEST)=
BEGIN
REGISTER SRCPTR, OLAST;
MAP FORMAT SRCPTR;
MAP FORMAT OLAST;
SRCPTR _ .DEST; ! PICK IT UP IN A REGISTER
IF .SRCPTR[S0OPCHAIN] NEQ 0 THEN RETURN; ! RETURN IF ALREADY IN THE CHAIN
IF (OLAST _ .LAST) EQL .SRCPTR THEN RETURN; ! RETURN IF ONLY IN CHAIN
LAST _ .SRCPTR; ! THIS IS NOW THE LAST
SRCPTR[S0OPPREV] _ .OLAST; ! OLD LAST IS THIS ONES PREVIOUS
SRCPTR[S0OPNEXT] _ 0; ! NEW LAST HAS NO NEXT
IF .OLAST EQL 0 THEN FIRST _ .SRCPTR ! IF ONLY, THEN FIRST TOO
ELSE OLAST[S0OPNEXT] _ .SRCPTR; ! ELSE THIS IS ITS NEXT
0
END;
COMMENT;
! MSGOUT SCHEDULES 1 OUTPUT FOR EACH TERMINAL DURING THE SCHEDULER LOOP
GLOBAL ROUTINE MSGOUT=
BEGIN
REGISTER SRCPTR,OPREV,ONEXT;
MAP FORMAT SRCPTR;
MAP FORMAT OPREV;
MAP FORMAT ONEXT;
SRCPTR _ .FIRST; ! GET FIRST TERMINAL IN OUTPUT CHAIN
UNTIL .SRCPTR EQL 0 DO
BEGIN
MSWRITE(.SRCPTR); ! TRY TO OUTPUT SOME DATA
IF .SRCPTR[S0IGHS] NEQ 0 THEN SRCPTR _ .SRCPTR[S0OPNEXT]
ELSE ! IF OUTPUT LAST GROUP, REMOVE FROM CHAIN
BEGIN
OPREV _ .SRCPTR[S0OPPREV]; ! GET OLD PREVIOUS
ONEXT _ .SRCPTR[S0OPNEXT]; ! AND NEXT
SRCPTR[S0OPCHAIN] _ 0; ! DISSOLVE LINKS
SRCPTR _ .ONEXT; ! SET UP FOR REST
IF .OPREV EQL 0 THEN ! REMOVING THE FIRST
IF .ONEXT EQL 0 THEN OPCHAIN _ 0 ! REMOVING THE ONLY
ELSE
BEGIN
FIRST _ .ONEXT; ! RESET FIRST
ONEXT[S0OPPREV] _ 0 ! IT HAS NO PREVIOUS
END
ELSE
IF .ONEXT EQL 0 THEN ! REMOVING THE LAST
BEGIN
LAST _ .OPREV; ! RESET THE NEW LAST
OPREV[S0OPNEXT] _ 0 ! IS HAS NO NEXT
END
ELSE
BEGIN
ONEXT[S0OPPREV] _ .OPREV; ! LINK REMAINING TOGETHER
OPREV[S0OPNEXT] _ .ONEXT ! TO COMPLETE THE CHAIN
END
END
END
END;
END;