PAM macros which are to be chained, and which do not necessarily have to refer to the same file, must be generated in list form by means of the operand MF=L and then stored in a constant area; chaining is implemented by specifying the CHAIN= operand.
All the macros (except the last) have the following format:
Operation | Operands | |
elementn | PAM | fcbaddr,operation,...,MF=L,CHAIN=elementn+1 |
In the last element of the chain, the CHAIN operand is omitted.
A chain of PAM macros in list form is called by means of a PAM macro with the following format:
Operation | Operands | |
PAM | MF=(E,element1) |
Only one SVC instruction is required for each chain, i.e. by chaining UPAM requests the user avoids the overhead of multiple SVC processing.
Example of coding
START LDBASE 10 USING *,10 . . PAM MF=(E,ELEM1) . . . TERM *CONSTANT-AREA ELEM1 PAM ......,MF=L,CHAIN=ELEM2 ELEM2 PAM ......,MF=L,CHAIN=ELEM3 ELEM3 PAM ......,MF=L . . . END
If execution is successful, the user regains control at the statement following the PAM macro which requested processing of an operand list chain.
All operations are carried out in exactly the same order in which the PAM macro lists appear within the chain – with one exception: when the first operation to request a lock is encountered, the rest of the chain is examined and all operations requesting locks are registered. If all the requested locks cannot be imposed within the specified time, the chain is terminated at the operation which requested the first lock.
If an action requested in the chain is not performed successfully, none of the following actions in the chain is executed (including locks).
Control is passed to the appropriate EXLST exit; register 1 points to the FCB of the file in which the error occurred. The error code (ID1ECB) and the sense byte (ID1XITB) are set in this FCB in the normal way, and field ID1CHERR in the FCB is set to the address of the element in the operand list chain that caused the error.
A check on an unfinished I/O operation also causes control to be transferred from the operand list chain to the user program at the specified address. The remaining requests in the chain (including locks) are not executed, and field ID1CHERR in the FCB is set to the address of the operand list element which contains the CHK operation. It is therefore not advisable to use check operations in operand list chains.
The user must ensure that the lock, read, write, wait, check and unlock operations are applied appropriately within a chain. Buffers and key fields are utilized by UPAM according to the request. A check is made to verify that a buffer exists and that access is authorized, but there is no guarantee that a buffer or a key field filled by an operation in a chain will not be overwritten by a later operation involving this chain.
The format of the PAM operand list can be described by means of a dummy program section (DSECT) generated with the IDPPL macro.
In all cases where a chain of UPAM operand lists cannot be processed in full (e.g. I/O operation failed, error detected, lock not accepted, EOF condition encountered, or CHK operation attempted on currently executing I/O request), the address of the first unexecuted chain entry is moved to field ID1CHERR of the FCB. The user can assume that all preceding entries were executed correctly.
UPAM does not report errors via FCB-EXIT and EXLST
if the UPAM SVC is executed and neither register 1 nor any chain operand contains a valid address (e.g. the address is not aligned on a word boundary or refers to a field which is not entirely within the user's virtual address space and is not large enough to accommodate a UPAM macro operand list, etc.);
if the FCB address in the UPAM macro operand list is either missing or invalid.
In both these cases, there is no FCB to which the error could be reported, and therefore UPAM aborts the program.
A UPAM operand list chain is validated in full before any function is initiated. If a CHAIN address or FCB address is found to be invalid, the job is aborted before any chain element is executed.
Where the eventing mechanism is used, the user program is likewise aborted if the I/O operation is completed and there is no event item available to which the event can be reported.