MVS 3.8 does no have any of the modern cross memory services available software or hardware. In order to communicate between address spaces some system level code must be used. Shared data can be placed into Common Service Area (CSA) storage which can be accessed by all address spaces. If address space A wants to send a message to address space B, address space A could copy the message into an area of CSA known by both A and B. The problem is how address space B knows the data is available. We could loop looking for changes but that would consume a lot of CPU time and would not be very efficient. We could look for changes and upon finding none we could wait some time interval before loooking again. If the delay interval is set too low a large amount of CPU time would still be consumed. If the interval is set too high the program becomes unresponsive since a delay is built in.
The normal way to synchronize between multiple tasks is to use the WAIT/POST functionality. A task issues a WAIT supervisor call pointing to an Event Control Block (ECB). The signaling task issues a POST supervisor call pointing to the same ECB to wake up the waiting task. This works very well inside a single address space but does not work across address spaces.
MVS does provide a way to POST and ECB in another address space. Is is a little more complicated than simply using the POST macro. In addition to the SVC interface to POST, MVS also provides a Branch Entry. Using Branch Entry is more complicated and requires the caller to be in supervisor mode and key zero. It does have the advantage of allowing us to post and ECB in an address space other than our own.
Below is a summary of the registers used as input for Branch Entry POST.
R10 - POST Completion Code (to be placed into ECB) R11 - ECB Address (high order bit of register must be set to X'80') R12 - Error Return Address R13 - ASCB Address of address space containing ECB R14 - Linkage Return Address R15 - Entry Point (CVT0PT01)
The high order bit of register 11 determines if the request is a cross memory post. When calling the Branch Entry POST routine for a non-cross memory post we must hold the Local Lock. For a cross memory post we do not have to hold any locks but we must be aware that the contents all registers except register 9 will be destroyed.
SRB Cross Memory Post
We now have enough to modify our simple SRB routine to post an ECB to signal a waiting task in another address space. We will begin by expanding our CSA storage map to include a parmameter list to be passed to the SRB routine.
WKAREA DSECT , PARMLIST DS 0F PARAMETER LIST FOR SRB ROUTINE WAITECB DS A ADDRESS OF LOCAL ECB WAITASCB DS A ADDRESS OF WAITING ASCB * SRBAREA DS CL(44) SRBCODE DS CL(ENDSRTN-SRBRTN) * * WKLEN EQU *-WKAREA
We will pass two parameters to the SRB routine. The first is the address of the waiting ECB located in the private area and the second is the address of the ASCB for the waiting address space. When our SRB routine is dispatched the address of the parmaeter list will be contained in register 1.
SRBRTN DS 0H LR R6,R15 SRB ROUTINE EP USING SRBRTN,R6 * LR R4,R1 SAVE PARM REGISTER USING PARMLIST,R4 * LR R9,R14 SAVE RETURN ADDRESS * * LA R10,X'7F' POST SLL R10,24 COMPLETION CODE * L R11,WAITECB ECB ADDRESS LA R1,X'80' SET SLL R1,24 HIGH-ORDER OR R11,R1 BIT * LA R12,POSTERR ERROR ROUTINE L R13,WAITASCB ASCB ADDRESS * L R15,CVTPTR CVT ADDRESS L R15,CVT0PT01-CVTMAP(,R15) POST BRANCH-ENTRY BALR R14,R15 * * BR R9 DONE - EXIT * * SRBCLEAN DS 0H SRB PURGE ROUTINE XC 0(SRBSIZE,R1),0(R1) BR R14 * * POSTERR DS 0H POST ERROR ROUTINE BR R14 * * LTORG ,
The first thing we do is copy the address of the parm list into register 4. Next we save the return address in register 9 (this is because register 9 is the only register preserved when we call Branch Entry POST). Next we set our post code into register 10. It can be anything we want so I chose X’7F000000′ but it really doesn’t matter. Next we load the address of the ECB into register 11 and set the high order bit to X’80’ to indicate a cross memory post. The address of our Post Error Routine goes into R12 and the address of the ASCB for the task that is waiting goes into R13. All the remains is to get the address of the Branch Entry Post routine into register 15 and then call it. Upon return the contents of all registers except R9 will be lost. Since all we need to do is exit all we need is the return address we saved in R9. We also added our Post Error Routine which immediately returns to the caller.
That’s it for the SRB routine but we still need some changes in our code that sets up and schedules the SRB.
L R9,CVTPTR CVT ADDRESS L R9,CVTASVT-CVTMAP(,R9) ASVT ADDRESS L R9,ASVTENTY-ASVT(,R9) FIRST ASCB POINTER L R9,4(,R9) ASCB FOR ASID=0002 (JES2)
We could continue to schedule the SRB into our own address space and call the cross memory post routine but we really should schedule the SRB routine into a different address space so we really are doing a cross memory post. I chose to use the JES2 address space since it is always active and I can be pretty confident it will be in ASID x’0002′. Again it really doesn’t matter for now and any valid address space could be used. To find the JES2 ASCB we get the Address Space Vector Table address from the CVT. We then offset to the list of pointers to ASCBs. The first entry is ASID x’0001′, the second ASID x’002′, and so on. We take the address of the second ASCB which should be the addres space for JES2. We save this address in R9.
ST R9,SRBASCB TARGET ASCB TO SCHEDULE TO
Next we need to place the address of the ASCB for JES2 into the SRB so it will be scheduled there.
LA R1,PARMLIST PARM LIST ST R1,SRBPARM * ST R8,WAITASCB SAVE OUR ASCB ADDRESS INTO PARMLIST * LA R1,LOCALECB ST R1,WAITECB
Now we have to set up the parameter list for the SRB routine. We place the pointer to the parm list into the SRB control block. The address of the ASCB for our address space goes into the parameter list along with the address of an ecb.
WAIT 1,ECB=LOCALECB WAIT FOR SRB TO COMPLETE
Now instead of setting a delay we wait for our ECB to be posted by the SRB routine.
LOCALECB DC F'0'
Here is the ECB we will wait on (located in our private storage).
IHAASVT ,
Finally we need to include the mapping macro for the ASVT. With this we are done and our program can be compiled, link edited and we can run it. If everything goes as planned it should run very quickly.
JOB 6755 $HASP373 SRB02 STARTED - INIT 12 - CLASS A - SYS TCS3 JOB 6755 15.39.08 0.00.00 0.00.00 0000 SRB02 MVSSP JOB 6755 15.39.08 0.00.00 0.00.00 0000 SRB02 ######## JOB 6755 $HASP395 SRB02 ENDED