|
The following program segment establishes and deletes the task
mode DESERV exit and thereby restores the previous task. The sample
is generic enough to apply to either the global or the task level
exit but shows here the task level support. When establishing a global
exit, obtain the DST storage in common storage.
Figure 1. Establishing and Deleting
a Task Level DESERV Exit Part 1 of 2 SAMPLE CSECT
USING *,12
STM 14,12,12(13) SAVE REGISTERS
LR 12,15 ESTABLISH BASE REGISTER
LA 2,SAVE ADDRESS REGISTER SAVE AREA
ST 2,8(13) FORWARD CHAIN SAVE AREA
ST 13,SAVE+4 BACKWARD CHAIN SAVE AREA
LR 13,2 ESTABLISH SAVE AREA
.
.
.
*
*
* ESTABLISH THE TASK LEVEL EXIT
*
* BUILD THE DST TO REPRESENT MY TASK LEVEL EXIT
*
LA 3,MY_DST ADDRESSABILITY TO MY DST
USING DST,3 MAP DST
XC DST,DST CLEAR MY DST STORAGE
MVC DST_ID,DST_ID_CONST SET EYECATCHER IN DST
LA 15,DST_LEN_IV(,0) GET LENGTH OF DST
ST 15,DST_LEN SET LENGTH OF DST
MVI DST_LEV,DST_LEV_IV SET LEVEL OF DST USED
OI DST_FLAGS,DST_FLAGS_PROP SET FLAG TO PROPAGATE THIS EXIT
* TO ATTACHED TASKS.
MVC DST_EXIT_PTR,ADDR_DESEXIT SET ADDRESS OF TASK EXIT
*
* CALL DESERV TO ENABLE MY TASK LEVEL EXIT
* THIS MODULE ASSUMES THAT IT IS RUNNING EITHER SUPERVISOR STATE
* OR SYSTEM KEY.
*
DESERV FUNC=EXIT, *
EXIT_SCOPE=TASK, *
EXIT_OPTION=REPLACE, *
EXIT_DST=MY_DST, *
EXIT_PREV_DSTPTR=MY_PREV_DSTPTR, *
MF=S
.
.
.
*
* QUERY THE CURRENT DST ADDRESS, RETURNED IN CURRENT_DSTPTR.
* THERE IS NO NEED TO QUERY PRIOR TO DOING THE DELETE, THIS IS
* HERE JUST TO SHOW THE INVOCATION SYNTAX.
*
DESERV FUNC=EXIT, *
EXIT_SCOPE=TASK, *
EXIT_OPTION=QUERY, *
EXIT_PREV_DSTPTR=CURRENT_DSTPTR, *
MF=S
Figure 2. Establishing and Deleting
a Task Level DESERV Exit Part 2 of 2 *
* HERE THE APPLICATION WOULD DO SOMETHING TO
* CAUSE A DESERV CALL TO BE DONE. AN EXAMPLE OF THIS TYPE OF THING
* WOULD BE ATTACHING THE BINDER AS A SUBTASK (THE BINDER USES
* DESERV.)
*
.
.
.
*
* DELETE THE TASK LEVEL EXIT
*
DESERV FUNC=EXIT, *
EXIT_SCOPE=TASK, *
EXIT_OPTION=DELETE, *
EXIT_DST=MY_DST, *
EXIT_PREV_DSTPTR=MY_PREV_DSTPTR, *
MF=S
.
.
.
*
* RESTORE REGISTERS AND RETURN
L 13,SAVE+4
LM 14,12,12(13)
SR 15,15 SET RETURN CODE
BR 14 RETURN TO CALLER
* THE FOLLOWING IS A BLOCK USED BY THIS APPLICATION. THIS BLOCK CAN
* BE USED BY THE EXIT. THE EXIT ALSO (SMARTLY) FINDS THE
* PREV_DST_PTR FIELD IN MY_BLOCK WHEN IT GIVES CONTROL TO THE
* PREVIOUSLY ESTABLISHED TASK LEVEL EXIT.
MY_BLOCK DS 0D MY APPLICATION BLOCK
MY_APPLICATION_STUFF DS CL8 MY APPLICATION STUFF
MY_DST DS CL(DST_LEN_IV) MY DST IMBEDDED IN MY BLOCK
MY_PREV_DSTPTR DS F ADDRESS OF PREVIOUS TASK LEVEL
EXTRN DESEXIT
ADDR_DESEXIT DC A(DESEXIT) ADDRESS OF MY TASK LEVEL EXIT
DST_ID_CONST DC CL8'IGWDST ' DST EYECATCHER
* DST
CURRENT_DSTPTR DS F ADDRESS OF CURRENT TASK LEVEL
* DST
SAVE DS 18F REGISTER SAVE AREA
END
The following program segment shows a sample DESERV exit. This
is the exit established by the previous segment of code. This sample
shows how to pass control to a previous exit. Note that this sample
exit is not reentrant, so it assumes there is only one subtask.
Figure 3. Sample DESERV Exit Routine
Part 1 of 3 DESEXIT CSECT
DESEXIT AMODE 31 Must be AMODE 31
DESEXIT RMODE ANY Could be RMODE 24 if required
*
* entry code to save registers and establish base register.
USING *,12
STM 14,12,12(13) SAVE REGISTERS
LR 12,15 ESTABLISH BASE REGISTER
LA 2,SAVE ADDRESS REGISTER SAVE AREA
ST 2,8(13) FORWARD CHAIN SAVE AREA
ST 13,SAVE+4 BACKWARD CHAIN SAVE AREA
LR 13,2 ESTABLISH SAVE AREA
*
* Assume this exit is only interested in the output from GET functions.
* Therefore ignore entry for all other functions and only
* process the get function invocations where get processing is complete
*
SLR 2,2 clear reg
ST 2,EXIT_RC initialize return code
LR 2,1 get the DESX address in reg 2
USING DESX,2 map the DESX
L 3,DESX_DST_PTR get address of DST
LR 4,3 get address of DST
LA 5,MY_DST-MY_BLOCK(,0) get offset to DST within MY_BLOCK
SR 4,5 get the address of MY_BLOCK
USING MY_BLOCK,4 map MY_BLOCK
*
* First give control to any previously established DESERV
* exits. If the value in PREV_DST_PTR is zero, then there was no
* previous DST (that is, no previous DESERV exit). PREV_DST_PTR was
* saved in MY_BLOCK by the SAMPLE CSECT that enabled this
* exit.
SR 15,15 simulate previous exit's return code
ICM 5,15,PREV_DST_PTR get previous DST address
BZ NOPREVDST branch if zero, no previous DST
* There was a previous exit, to which you transfer control.
* First build a DESX then branch to the previous exit.
*
*
* Getmain dynamic storage for interfacing with the other exit
*
*
GETMAIN RU,LV=DESX_LEN_IV,SP=230,KEY=0,LOC=(ANY)
ST 1,MY_DESX_STG_PTR
MVC 0(L'DESX,1),DESX copy the DESX that was input to this
* routine.
ST 5,DESX_DST_PTR-DESX(,1) Set previous DST address in DESX
L 15,DST_EXIT_PTR-DST(,5) get address of previous exit
BALR 14,15 call the previous exit in 31 bit amode
Figure 4. Sample DESERV Exit Routine
Part 2 of 3 NOPREVDST EQU *
ST 15,EXIT_RC save previous exit's return code
* If this invocation of the exit was the pre-processing exit and the
* exit we called just returned with a return code of 4 then they
* might have returned the data in question.
TM DESX_FLAGS,DESX_POST_BIT is this post-processing call
BO POST yes, branch
* this is a pre-processing call, did the exit just called request an
* immediate return, and therefore maybe fill in the output fields
* if the return code was zero, the called routine wants deserv to
* perform the function.
CLC EXIT_RC,ZERO was return code zero
BE RETURN yes, branch to return to deserv
POST EQU * either called exit performed the
* deserv function, or this is a post
* processing exit call.
L 6,DESX_DESP_PTR get the DESERV parameter list (DESP)
USING DESP,6 map DESP
CLI DESP_FUNC,DESP_FUNC_GET is this a function GET call
BNE RETURN no, branch
CLC DESX_REASON_CODE+2(2),=AL2(DESRS_SUCC) check low order
* halfword of reason code for success
BE GOODDATA branch if DESERV GET was successful
CLC DESX_REASON_CODE+2(2),=AL2(DESRS_NOTFOUND) check for
* some members not found
BNE BADDATA branch if some other error
GOODDATA EQU *
*
* Process the entries in the names list that were found
*
.
.
.
B RETURN return to the caller (DESERV)
BADDATA EQU *
.
.
.
*
RETURN EQU * Return to caller (DESERV)
*
* restore registers, FREEMAIN storage, etc.
*
L 15,EXIT_RC set return code
L 13,SAVE+4
L 14,12(13) restore return address
LM 0,12,20(13) restore callers other registers
BR 14 return to deserv
Figure 5. Sample DESERV Exit Routine
Part 3 of 3 *
* CONTROL INFORMATION
*
SAVE DS 18F REGISTER SAVE AREA
ZERO DC F'0' constant of zero
EXIT_RC DC F'0' Return code to pass back to DESERV
DESX_ID_CONST DC CL8'IGWDESX ' EYECATCHER FOR DESX
MY_DESX_STG_PTR DC F'0' ADDRESS OF GETMAINED STORAGE FOR
* DESX TO PASS TO PREVIOUS EXIT.
MY_BLOCK DSECT MY APPLICATION BLOCK
MY_APPLICATION_STUFF DS CL8 MY APPLICATION STUFF
MY_DST DS CL(DST_LEN_IV) MY DST IMBEDED IN MY BLOCK
PREV_DST_PTR DS F ADDRESS OF PREVIOUS TASK LEVEL EXIT
IGWDES DESERV MAPPINGS
IGWSMDE DIRECTORY ENTRY
IEWPMAR PROGRAM MANAGEMENT ATTRIBUTE RECORD
* THE PMAR IS A SUB RECORD OF THE SMDE
END
|