Cross Memory Post

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