User Written Subroutines

As multiple FOCUS users function within the same MVS address space, it may be necessary for user-written subroutines to coordinate between themselves the use of MVS services. To this end MSO provides services that MSO sites can use to write user written subroutines that operate properly in a multiple-task address space.

In this section:

User Common Memory

MSODBLW: Retrieve the User Doubleword Address

DDname Translation: The MSODDX Subroutine

MSODDX Calling Environment

Usage of MSODDX in a Typical Application

MSODDX Parameter List

Sample Assembler Call

Link-Edit Example

MSUSRXT, the MSO initialization and termination exit, and the MSODBLW subroutine exist to provide these services.

User Common Memory

MSO provides eight bytes of user memory that can be used by a site to allow the users in an MSO address space to share memory and coordinate services. The location of the eight bytes of memory can be obtained in a variety of ways, including the MSUSRXT and MSSMFXT user exits. The MSODBLW exit allows any MSO user written subroutine to obtain the address of the user doubleword at any time.

Usually, the user doubleword will be used by a site as the repository of the address of GETMAINed memory that is to be used by all the users in an MSO address space. Once all users can share some common memory, any MVS service that requires coordination between users can be used. For instance, a user-written subroutine for an MSO user can be written that does I/O independently of MSO that does not interfere with other MSO users using the same subroutine. As long as this subroutine enqueues on some resource and dequeues on the resource after the I/O is done, any number of MSO users can use the user-written subroutine without interfering with each other. The name of the resource would be present in the common memory all users share.


Top of page

MSODBLW: Retrieve the User Doubleword Address

MSODBLW is a program that can be called within an MSO user written subroutine to retrieve the address of the user doubleword. This program is present in object form in MSO.DATA(MSODBLW). To obtain the address of the user doubleword, a user-written subroutine calls MSODBLW with two parameters: first, the address of a 300 byte workspace to be used by MSODBLW, and second, a fullword into which MSODBLW will insert the address of the user doubleword. The 300-byte workspace for MSODBLW must be non-sharable. The safest way to provide this space is to GETMAIN it in the user-written subroutine before the exit is called. MSODBLW is fully reentrant, and may be called in AMODE 24 or AMODE 31.

A user-written subroutine that calls MSODBLW simply links the object code MSO.DATA(MSODBLW) into the user-written subroutine module.


Top of page

DDname Translation: The MSODDX Subroutine

MSODDX is a utility routine intended to be incorporated into user-written subroutines that will be accessing ddnames allocated to a FOCUS/MSO user. Its function is to provide a data adapter to MSO's ddname translation services, so that your program is able to access files under the same ddname MSO uses.

A good example of a routine that requires the use of the MSODDX utility is the FINDMEM user-written subroutine. FINDMEM is passed a ddname, a member name, and a return code field, and opens the specified ddname to determine if a member with the given name exists in the file. Under MSO, which is using ddname translation, FINDMEM must call MSODDX to determine the correct ddname to open.

Why are ddnames handled differently under MSO? Under MSO, each of the many FOCUS users want to allocate files according to their individual needs. Thus there is likely to be a different allocation for FOCEXEC, MASTER, etc., in each FOCUS task. In order to keep each user's allocations separate, MSO uses a scheme called ddname translation to create unique ddnames for every file belonging to each user. When a user allocates a file, MSO generates a unique name to use to perform the allocation, and saves, in a table, the relationship between the ddname the user sees, and the ddname that MSO uses for the actual allocation.

Only files allocated locally, by the individual FOCUS user, participate in this ddname translation scheme. Ddnames that are present in the MSO start-up JCL are not translated, and are referred to as global ddnames, since they are available to all of the FOCUS/MSO tasks. Global ddnames do not require the MSODDX routine, as they are not translated.

Since the allocation performed within the FOCUS session is not done under the same ddname originally specified by the user, when a user-written subroutine is to access one of those files, the program must find out what ddname has actually been used, and use the actual name when opening the file. This can be accomplished by calling the MSODDX routine to perform the translation for you.


Top of page

MSODDX Calling Environment

The MSODDX routine offers a flexible data adapter. It is fully reentrant, may be called by a program in either AMODE 31 or AMODE 24, and returns valid results under FOCUS environments outside of MSO, including TSO and batch FOCUS. If you call it while executing in AMODE 24 (below the line), you must provide all data areas and addresses below the line as well.

MSODDX may be called from an assembly-language program or any high-level language that supports dynamic specification of the ddname to be opened. Some languages that do this are PL/I and C. Languages that require the ddname to be hard-coded at compilation time are not suitable. Consult the documentation for your particular compiler for further information.


Top of page

Usage of MSODDX in a Typical Application

The most likely use for MSODDX is simply to be able to code a user-written subroutine that is callable under MSO, and will open and process a file for you. For such a routine, you will want to call MSODDX once for each file that you open, immediately before issuing the OPEN. Use a CALLTYPE of 1 (see parameters below for more information on CALLTYPE=1), and pass the generic ddname, or, in other words, the ddname that the user specified when the file was allocated. The correct ddname is returned to you, and you will either place this into the DCB (using ASSEMBLER), or into a variable (for a high-level language). Then you will issue the OPEN, and the remainder of your application proceeds normally. You do not need to test for MSO in your application. If you call MSODDX when not under MSO, it merely returns the same ddname you have passed it.


Top of page

MSODDX Parameter List

MSODDX uses the standard OS-calling conventions. Register 1 must point to a list of fullword addresses, which point to the parameters described below; Register 13 must point to a 72-byte register savearea; Register 15 contains the entry point address of MSODDX; and Register 14 contains the return address to your program (this is all done for you in a high-level language call). The parameters are labeled to indicate whether a value is expected on input (I) to MSODDX, or will contain a value upon return from MSODDX (O).

Note: For assembler-language callers the return code is provided as one of the parameters, and is not given in Register 15 (R15 is returned unchanged).

Input/Output

Field

Contents

(I)

CALLTYPE

The function to be performed. CALLTYPE is a fullword (4-byte integer) containing one of the following values:

0 - Check whether we are currently running under MSO. RETCODE is 0 if YES, 4 if NO. WORKAREA is required. GENDD and TRANDD are not referenced.

1 - The STANDARD call. You provide the generic ddname (for example, FOCEXEC) in GENDD. The correct ddname to use is returned in TRANDD. WORKAREA is required. The RETCODE is 0 if the ddname is known to MSO, either for this individual FOCUS user, or as a ddname known globally to all MSO users. 4 means the ddname is not known to MSO (TRANDD will be set equal to GENDD, so it is not necessary to check RETCODE before using TRANDD).

When called outside of MSO, TRANDD is set equal to GENDD. RETCODE is set to 0 if the ddname exists, or to 4 if the ddname does not exist.

2 - Untranslation. You provide a translated ddname in TRANDD, the generic ddname it came from is returned in GENDD. If TRANDD is not found to be a translated ddname, then GENDD is set equal to TRANDD. RETCODE is 0 if TRANDD is a translated ddname, 4 otherwise. WORKAREA is required.

Is always set to the same value as GENDD.

3 - Create a translated ddname. Use only when your user-written subroutine will be performing dynamic allocation. Provide the generic ddname you intend to use in GENDD. If GENDD is not already in use, a new TRANDD is returned, and RETCODE is 0. If the ddname in GENDD is already in use, TRANDD is set equal to GENDD, and RETCODE is set to 4. WORKAREA is required.

When called outside of MSO, TRANDD.

4 - Delete a translated ddname previously created using a CALLTYPE 3 call. Use when your user-written subroutine will be dynamically freeing the ddname it had previously allocated. Provide the generic ddname in GENDD. If found and removed, RETCODE is 0. RETCODE is 4 if an error was encountered. WORKAREA is required.

When called outside of MSO, this call will do nothing.

(I/O)

GENDD

The generic (untranslated) ddname. GENDD is an eight-byte character field. Its usage is described under the CALLTYPEs above, as it varies based on the CALLTYPE value.

(I/O)

TRANDD

The actual (translated) ddname. TRANDD is an eight-byte character field. Its usage is described under the CALLTYPEs above, as it varies based on the CALLTYPE value.

(I)

WORKAREA

A 300-byte workarea for MSODDX's use. WORKAREA is a 300-byte area used by MSODDX for its workarea. You must initialize this area to low values (hex zeroes) prior to the first call you make to MSODDX, and should not alter its contents from then on.

(O)

RETCODE

The return code from MSODDX. RETCODE is a fullword (4-byte integer) providing an indication of the results of the call made to MSODDX. The only values ever returned will be zero and four; their meanings are described under the CALLTYPEs above, as their meaning varies based on the CALLTYPE performed.


Top of page

Sample Assembler Call

This is a sample of the calling sequence and data areas that you may set up in your program for calling MSODDX. A program running in AMODE 24 is being assumed here (because the DCB must be below the line).

         CALL MSODDX,(CALLTYPE,GENDD,TRANDD,WORKAREA,                    X
RETCODE),VL call MSODDX
LA R3,MYDCB point to the DCB
USING DCB,R3 use DSECT to reference DCB fields
MVC DCBDDNAM,TRANDD move correct ddname into DCB
DROP R3 drop the dsect's base register
OPEN (MYDCB,(INPUT)) now open the file with real DD etc...
CALLTYPE DC F'1' return translated ddname
GENDD DC CL8'SAMPLE' the generic one known to FOCUS user
TRANDD DC CL8' ' the name to use
WORKAREA DC 300X'00' workarea for MSODDX
RETCODE DC F'0' the return code
 
* sample DCB
MYDCB DCB DDNAME=X,DSORG=PO,MACRF=R a sample DCB for a PDS
* macro to obtain DSECT of the DCB
DCBD DSORG=PO include this macro for DSECT of the DCB
etc...

Top of page

Link-Edit Example

To incorporate MSODDX into your program, link-edit it with your program to create the load module for your user-written subroutine. The object code for MSODDX can be found in MSO.DATA, member MSODDX. Below is a sample of a link-edit job that might be used. You will need to make changes to adapt this to your particular needs.

//MSODDX JOB
//LINK EXEC PGM=IEWL,PARM='XREF'
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//MSODATA DD DSN=MSO.DATA,DISP=SHR
//MYPGM DD DSN=my.object.library,DISP=SHR
//SYSLMOD DD DSN=FOCLIB.LOAD,DISP=SHR
//SYSLIN DD *
INCLUDE MYPGM(program)
INCLUDE MSODATA(MSODDX)
ENTRY program
NAME program(R)
/*

Information Builders