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]