z/OS DFSMS Using Data Sets
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


Processing Sequential and Partitioned Data Sets

z/OS DFSMS Using Data Sets
SC23-6855-00

Data management is designed to provide a balance between ease of use, migration to new releases, coexistence with various levels of software and hardware, device independence, exploitation of hardware features, and performance. Sometimes these considerations can conflict. If your program exploits a particular model's features to maximize performance, it might not take full advantage of newer technology.

It is the intent of IBM that your programs that use documented programming interfaces and work on the current level of the system will run at least equally well on future levels of the system. However, IBM cannot guarantee that. Characteristics such as certain reason codes that are documented only in z/OS DFSMSdfp Diagnosis are not part of the intended programming interface. Examples of potential problems are:
  • Your program has a timing dependency such as a READ or WRITE macro completes before another event. In some cases READ or WRITE is synchronous with your program.
  • Your program tests a field or control block that is not part of the intended programming interface. An example is status indicators not documented in Figure 1.
  • Your program relies on the system to enforce a restriction such as the maximum value of something. For example, the maximum block size on DASD used to be less than 32 760 bytes, the maximum NCP value for BSAM used to be 99 and the maximum block size on tape used to be 32 760.
  • New releases might introduce new return and reason codes for system functions.

For these reasons, the operating system has many options. It is not the intent of IBM to require extensive education to use assembly language programming. The purpose of this topic is to show how to read and write sequential data sets simply in High Level Assembler while maximizing ease of use, migration potential, the likelihood of coexistence, and device independence, while getting reasonable performance.

You can use the examples in this topic to read or write sequential data sets and partitioned members. These include ordinary disk data sets, extended format data sets, compressed format data sets, PDS members, PDSE members, UNIX files, UNIX FIFOs, spooled data sets (SYSIN and SYSOUT), real or VM simulated unit record devices, TSO/E terminals, magnetic tapes, dummy data sets, and most combinations of them in a concatenation.

Recommendations:
  • Use QSAM because it is simpler. Use BSAM if you need to read or write nonsequentially or you need more control of I/O completion. With BSAM you can issue the NOTE, POINT, CNTRL, and BSP macros. These macros work differently on various device classes. See Record Format—Device Type Considerations and Achieving Device Independence. Use BPAM if you need to access more than one member of a PDS or PDSE.
  • Specify LRECL and RECFM in the DCB macro if your program's logic depends on the record length and record format. If you omit either of them, your program is able to handle more types of data but you have to write more code. See Selecting Record Formats for Non-VSAM Data Sets.
  • Use format-F or format-V records, and specify blocking (RECFM=FB or VB). This allows longer blocks. Format-U generally is less efficient. Format-D works only on certain types of tape.
  • Omit the block size in the DCB macro. Code BLKSIZE=0 in the DCBE macro to use the large block interface. When your program is reading, this allows it to adapt to the appropriate block size for the data set. If the data set has no label (such as for an unlabeled tape), the user can specify the block size in the DD statement or dynamic allocation. For some data set types (such as PDSEs and UNIX files) there is no real block size; the system simulates any valid block size and there is a default.

    When your program is writing and you omit DCB BLKSIZE and code DCBE BLKSIZE=0, this enables the user to select the block size in the DD statement or dynamic allocation. The user should only do this if there is a reason to do so, such as a reading program cannot accept large blocks. If the user does not specify a block size, OPEN selects one that is valid for the LRECL and RECFM and is optimal for the device. Coding BLKSIZE=0 in the DCBE macro lets OPEN select a block size that exceeds 32 760 bytes if large block interface (LBI) processing is being used, thereby possibly shortening run time significantly. If OPEN might select a block size that is larger than the reading programs can handle, the user can code the BLKSZLIM keyword in the DD statement or the dynamic allocation equivalent or rely on the block size limit in the data class or in the DEVSUPxx PARMLIB member.

    If you want to provide your own default for BLKSIZE and not let OPEN do it, you can provide a DCB OPEN exit routine. See DCB OPEN Exit. The installation OPEN exit might override your program's selection of DCB parameters.

  • Omit BUFL (buffer length) because it relies on the value of the sum of BLKSIZE and KEYLEN and because it cannot exceed 32 760.
  • Omit BUFNO (number of buffers) for QSAM, BSAM, and BPAM and NCP if you use BSAM or BPAM. Let OPEN select QSAM BUFNO. This is particularly important with striped data sets. The user can experiment with different values for QSAM BUFNO to see if it can improve run time.

    With BSAM and BPAM, code MULTSDN and MULTACC in the DCBE macro. See Improving Performance for Sequential Data Sets.

    With QSAM, BSAM, and BPAM this generally has no effect on the EXCP count that is reported in SMF type 14, 15, 21, and 30 records. On DASD, this counts blocks that are transferred and not the number of channel programs. This causes the counts to be repeatable and not to depend on random factors in the system.

  • Omit BUFOFF because it works only with tapes with ISO/ANSI standard labels or no labels.
  • If you choose BSAM or BPAM in 31-bit addressing mode, do not use the BUILD or GETPOOL macro and do not request OPEN to build a buffer pool. If you code a nonzero BUFNO value, you are requesting OPEN to build a buffer pool. Such a buffer pool resides below the line. Use your own code to allocate data areas above the line.
  • Code A or M for RECFM or code OPTCD=J only if your program logic requires reading or writing control characters. These are not the EBCDIC or ASCII control characters such as carriage return, line feed, or new page.
  • Omit KEYLEN, DEVD, DEN, TRTCH, MODE, STACK, and FUNC because they are device dependent. KEYLEN also makes the program run slower unless you code KEYLEN=0. The user can code most of them in the DD statement if needed.
  • Omit BFALN, BFTEK, BUFCB, EROPT, and OPTCD because they probably are not useful, except OPTCD=J. OPTCD=J specifies that the records contain table reference characters. See Table Reference Character.
  • LOCATE mode (MACRF=(GL,PL)) might be more efficient than move mode. This depends on your program's logic. The move mode requires QSAM to move the data an extra time.
  • If your program runs with 31-bit addressing mode (AMODE), code RMODE31=BUFF in the DCBE so that the QSAM buffers are above the 16 MB line. A nonreentrant, RMODE 24 program (residing below the 16 MB line) is simpler than a reentrant or RMODE 31 program because the DCB must reside below the line in storage that is separate for each open data set.
  • Code a SYNAD (I/O error) routine to prevent the 001 ABEND that the system issues when a data set has an I/O error. In the SYNAD routine, issue the SYNADAF macro, write the message, and terminate the program. This writes a message and avoids a dump because the dump is not likely to be useful.
  • Use extended-format data sets even if you are not using striping. They tend to be more efficient, and OPEN provides a more efficient default for BUFNO. Avoid writing many blocks that are shorter than the maximum for the data set because short blocks waste disk space.
  • If using dynamic allocation on non-VSAM data sets allocated by your application program, and if the NON_VSAM_XTIOT=YES option of the DEVSUPxx member of PARMLIB is in effect, code LOC=ANY on the DCBE macro in your program. You should always set this option before issuing an OPEN macro as the application program signifies that the allocation can have an XTIOT that can reside above the line (instead of a TIOT entry), the UCB can reside above the line and the DSAB can reside above the line. If any of these three is true, then OPEN will set the two-byte DCBTIOT field to zero instead of setting it to an offset in the TIOT, and the application program will be able to OPEN and process the data set allocated dynamically with an associated XTIOT. The XTIOT, NOCAPTURE, and DSAB above the line option of dynamic allocation will give VSCR benefits because each XTIOT is above the line. Additionally, with XTIOTs come an increase on the limit of non-VSAM data sets that can be allocated and opened in an address space at one time. This limit for non-VSAM, non-XTIOT, data sets is about 3200 single volume data sets. Whereas, the non-VSAM, XTIOT limit is 100,000 data sets. A major problem addressed by supporting more than 3200 single volume data sets is VSCR.
    Note: If the application program sets the DCBE option before OPEN, but the NON_VSAM_XTIOT option of the DEVSUPxx member of PARMLIB is not in effect, then OPEN will issue an ABEND 113–4C and a message IEC142I.
Figure 1 shows the simplest way to read a sequential data set.
Figure 1. Reading a Sequential Data Set
         OPEN    (INDCB,INPUT)          Open to read
         LTR     R15,R15                Branch if DD name seems not
         BNZ    ...                      to be defined
* Loop to read all the records
LOOP     GET     INDCB                  Get address of a record in R1
         ...                            Process a record
         B       LOOP                   Branch to read next record
* I/O error routine for INDCB
IOERROR  SYNADAF ACSMETH=QSAM           Get message area
         MVI    6(R1),X'80'             Set WTO MCS flags
         MVC    8(16,R1),=CL16'I/O Error' Put phrase on binary fields
         MVC    128(4,R1),=X'00000020'   Set ROUTCDE=11 (WTP)
         WTO    MF=(E,4(R1))            Write message to user
         SYNADRLS                       Release SYNADAF area, fall through
* The GET macro branches here after all records have been read
EOD      CLOSE  (INDCB)                 Close the data set
         FREEPOOL INDCB                 Free the QSAM buffer pool
         ...                            Rest of program
INDCB    DCB    DDNAME=INPUT,MACRF=GL,RECFM=VB,    Must be format-V           *
                DCBE=INDCBE
INDCBE   DCBE   EODAD=EOD,SYNAD=IOERROR,BLKSIZE=0  Request LBI
Figure 2 is the same as Figure 1 but converted to be reentrant and reside above the 16 MB line:
Figure 2. Reentrant—Above the 16 MB Line
COPYPROG CSECT
COPYPROG RMODE ANY
COPYPROG AMODE 31
         GETMAIN R,LV=Arealen,LOC=(BELOW,64)
         LR      R11,R1
         USING   MYAREA,R11
         USING   IHADCB,InDCB
         USING   DCBE,INDCBE
         MVC     IHADCB(AreaLen),MYDCB    Copy DCB and DCBE
         LA      R0,DCBE                  Point DCB copy to
         ST      R0,DCBDCBE               DCBE copy
         OPEN    (IHADCB,),MF=(E,INOPEN)  Open to read
         LTR     R15,R15                  Branch if DDname seems not
         BNZ     ...                        to be defined
* Loop to read all the records
LOOP     GET     INDCB                    Get address of a record in R1
         ...                              Process a record
         B       LOOP                     Branch to read next record
* I/O error routine for INDCB
IOERROR  SYNADAF ACSMETH=QSAM             Get message area
         MVI    6(R1),X'80'               Set WTO MCS flags
         MVC    8(16,R1),=CL16'I/O Error'  Put phrase on binary fields
         MVC    128(4,R1),=X'00000020'    Set ROUTCDE=11 (WTP)
         WTO    MF=(E,4(R1))              Write message to user
         SYNADRLS                         Release SYNADAF area, fall through
* The GET macro branches here after all records have been read
EOD      CLOSE  MF=(E,INOPEN)           Close the data set
* FREEPOOL not needed due to RMODE31=BUFF
         ...                            Rest of program
MYDCB    DCB    DDNAME=INPUT,MACRF=GL,RECFM=VB,                               *
                DCBE=MYDCBE
MYDCBE   DCBE   EODAD=EOD,SYNAD=IOERROR,BLKSIZE=0,RMODE31=BUFF
         OPEN   (,INPUT),MF=L,MODE=24
AreaLen  EQU    *-MYDCB
         DCBD   DSORG=QS,DEVD=DA
         IHADCBE                        Could be above 16 MB line
MYAREA   DSECT
INDCB    DS     XL(DCBLNGQS)
INDCBE   DS     XL(DCBEEND-DCBE)
INOPEN   OPEN   (,),MF=L

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014