The Exit Routine terminates the top level RB and makes the next RB on the stack active. If there are no more RB’s on the stack then the TCB is terminated.
000000 9 TXXEXIT CSECT ,
000000 18CF 10 LR R12,R15
00000 11 USING TXXEXIT,R12
12 *
000002 8000 C0C8 000C8 13 SSM =X'00' DISABLE INTERRUPTS
14 *
000006 5840 0010 00010 15 L R4,16 CVT ADDRESS
00000A 5840 4000 00000 16 L R4,CVTCTCB-@CVT(,R4) GET TCB ADDRESS
00000E 5850 4008 00008 17 L R5,TCBRB-@TCB(,R4) GET RB ADDRESS
18 *
00000 19 USING @TCB,R4
00000 20 USING @RB,R5
21 *
000012 1255 22 LTR R5,R5 ANY RB
000014 4780 C068 00068 23 BZ XTCB NO - TERMINATE TCB
Interrupts are disabled before any additional processing is done. Since we will be modifying RB and TCB chains we don’t want the Dispatcher trying to dispatch a TCB we are modifying. By disabling interrupts we know the Dispatcher will not gain control through an interrupt caused by the Interval Timer or and I/O interrupt. We next get the current TCB address and the top level RB address. If for some reason there is no RB we terminate the TCB.
000018 D23F 4020 5010 00020 00010 25 MVC TCBREGS(64),RBREGS COPY RB REGS TO TCB
00001E D207 4018 5008 00018 00008 26 MVC TCBPSW(8),RBPSW COPY RB PSW TO TCB
000024 5810 5000 00000 27 L R1,RBNEXT NEXT RB ON CHAIN
000028 5010 4008 00008 28 ST R1,TCBRB UNCHAIN RB
29 *
00002C 4110 0050 00050 30 LA R1,RBLEN LENGTH OF RB
000030 BF18 C0C9 000C9 31 ICM R1,B'1000',=AL1(128) SP=128
000034 1805 32 LR R0,R5 RB ADDRESS TO FREE
33 @CALL FREEMAIN FREE STORAGE
000036 58F0 0014 00014 34+ L R15,20 MVT ADDRESS
00003A 58F0 F01C 0001C 35+ L R15,MVTFMAIN-@MVT(,R15) ROUTINE ADDRESS
00003E 05EF 36+ BALR R14,R15
We unchain the top level RB by taking the forward pointer in the RB and storing it in the TCB. Now that the RB is off the chain we can free the storage associated with it.
000040 5850 4008 00008 38 L R5,TCBRB GET NEW CURRENT RB ADDRESS
000044 1255 39 LTR R5,R5 ANY RB
000046 4780 C068 00068 40 BZ XTCB NO - TERMINATE TCB
41 *
00004A 9500 5004 00004 42 CLI RBWTCNT,0 IS RB WAITING
00004E 4780 C05A 0005A 43 BE EXIT010 NO - BRANCH
44 *
000052 9680 4004 00004 45 OI TCBFLGS,TCBFWAIT SET WAIT BIT
000056 47F0 C05E 0005E 46 B EXIT020
48 *
00005A 49 EXIT010 DS 0H
00005A 947F 4004 00004 50 NI TCBFLGS,X'FF'-TCBFWAIT CLEAR WAIT BIT
00005E 51 EXIT020 DS 0H
00005E 58F0 0014 00014 52 L R15,20 MVT ADDRESS
000062 58F0 F004 00004 53 L R15,MVTDISP-@MVT(,R15) DISPATCHER ENTRY
000066 07FF 54 BR R15 GO TO DISPATCHER
Next we get the new top level RB address. If we just removed the last RB for the TCB this pointer will be null and we need to terminate the TCB. If there is a top level RB we propagate the wait status of the RB to the TCB. If the RB wait count is not zero the TCB wait flag is set. If the RB wait count is zero the TCB wait flag is cleared. Control is then transferred to the Dispatcher to select the next task to dispatch.
000068 57 XTCB DS 0H
000068 5810 0010 00010 58 L R1,16 CVT ADDRESS
00006C 5810 1004 00004 59 L R1,CVTTASKQ-@CVT(,R1) TOP OF TASK QUEUE
60 *
000070 61 XTCB010 DS 0H
000070 5820 1000 00000 62 L R2,0(,R1) POINT TO NEXT TCB
000074 1222 63 LTR R2,R2 END OF CHAIN ?
000076 4780 C0B8 000B8 64 BZ XTCB900 SHOULD NOT HAPPEN - CAN'T FIND TCB
65 *
00007A 1924 66 CR R2,R4 IS THIS OUR TCB
00007C 4780 C086 00086 67 BE XTCB020 YES - BRANCH
68 *
000080 1812 69 LR R1,R2 CHECK NEXT
000082 47F0 C070 00070 70 B XTCB010 TCB
This routine terminates the TCB when no RB’s are left. First the the TCB chain is searched to locate the TCB that points to the TCB we are terminating. We need this TCB address so we can unchain the terminating TCB.
000086 73 XTCB020 DS 0H
000086 5830 2000 00000 74 L R3,0(,R2) UNCHAIN THIS
00008A 5030 1000 00000 75 ST R3,0(,R1) TCB FROM QUEUE
76 *
00008E 58B0 0010 00010 77 L R11,16 CVT
000092 5810 B004 00004 78 L R1,CVTTASKQ-@CVT(,R11) TOP OF QUEUE (WAIT TASK)
000096 5010 B000 00000 79 ST R1,CVTCTCB-@CVT(,R11) MAKE CURRENT TASK
80 *
00009A 4110 0060 00060 81 LA R1,TCBLEN LENGTH OF TCB
00009E BF18 C0C9 000C9 82 ICM R1,B'1000',=AL1(128) SP=128
0000A2 1804 83 LR R0,R4 ADDRESS OF TCB TO FREE
84 @CALL FREEMAIN
0000A4 58F0 0014 00014 85+ L R15,20 MVT ADDRESS
0000A8 58F0 F01C 0001C 86+ L R15,MVTFMAIN-@MVT(,R15) ROUTINE ADDRESS
0000AC 05EF 87+ BALR R14,R15
88 *
0000AE 58F0 0014 00014 89 L R15,20 MVT ADDRESS
0000B2 58F0 F004 00004 90 L R15,MVTDISP-@MVT(,R15) DISPATCHER
0000B6 07FF 91 BR R15
The TCB is removed from the chain and the Wait Task is made the current task. This is necessary so the current task pointer will point to a valid TCB. Now the TCB storage is freed and control is passed to the Dispatcher.
0000B8 95 XTCB900 DS 0H
0000B8 8200 C0C0 000C0 96 LPSW XTCBPSW
97 *
0000C0 98 DS 0D
0000C0 0002000000EE0005 99 XTCBPSW DC AL1(0,2,0,0),A(@E@EXIT)
If the terminating TCB is not found on the TCB chain an unrecoverable error has occurred and a wait state PSW is loaded.
[Next – SVC 3 – Exit]