gtpa2m0mApplication Programming

Entry Control Block

The entry control block (ECB) is the primary interface between TPF and the application program. TPF creates an ECB for every message entering the system and follows the processing of that message throughout its life in the system. Additional entries (ECBs) may be created at the request of the application to subdivide the processing. Among other things, the ECB contains an activation number, switches, counters, two limited work areas, and pointers to additional data in main storage or in file storage. The ECB thus enables the application to control its processing and to request services from TPF to control file storage and main storage, transmit messages, and pass control among program segments.

The assembler application accesses its ECB through general register 9. This register is reserved in the TPF system for this function. At all times there is a pointer in register 9 to a unique ECB that is being referenced by the application program in control. The program, in turn, is pointed to by another dedicated register, register 8.

The C or C++ language application accesses its ECB through linkage generated by the IBM C and C++ compiler products on the System/390 platform. The ecbptr macro is available to the application programmer to access information in the ECB. The ecbptr macro returns a pointer to a structure of type eb0eb to the currently executing ECB. This structure is defined in the c$eb0eb.h header.

The ECB enables application programs to be reentrant, a crucial feature of TPF's high performance. To be reentrant, an application program refers to switches, counters, and pointers in the ECB and not in the program itself.

TPF dynamically maintains all references to system storage, register content and usage in the ECB. Consequently, one main storage copy of a program, by referring to different ECBs, is able to process many different messages in various stages of progress.

Whether in assembly language or C language the ECB is defined in great detail; almost every byte has its own symbolic name. The assembly language DSECT that defines the symbolic names and displacements in the ECB is named EB0EB. The c$eb0eb.h header defines the symbolic names and displacements in the ECB for C language.

In assembly language the EB0EB macro does not have to be coded explicitly because it is called by the BEGIN macro, which must be the first statement in every ECB-controlled assembler language program. In C language, if a program refers to ECB fields, you must include the c$eb0eb.h header, either explicitly or implicitly.

In C language the last 3 or 4 characters of the symbolic names specified in c$eb0eb.h are used as dump tags to identify ECB fields in a main storage dump. For example, W032 in a main storage dump identifies ebw032 in application work area 1.

Note:
The corresponding ECB fields are listed in lowercase in the C language and uppercase in assembler.

There are 3 categories of ECB fields:

Table 1 summarizes the fields of greatest importance in application programming. Study the EB0EB DSECT in assembly language or the c$eb0eb.h header in C language for an understanding of the ECB fields in this critical block.

Table 1. Summary of the Entry Control Block Application and Interface Areas

Field(s) Area
ebw000-ebw103
ebsw01-ebsw03
ebrs01
ebcm01-ebcm03
eber01
Application interprogram work area 1
ce1fa0-ce1faf File address reference words (FARW)
ce1cr0-ce1crf Core block reference words (CBRW)
ce1fx0-ce1fxf File reference address word extensions (FAXW)
ce1sud, ce1sug System error indicators
ce1rda-ce1svp TPF register save area
ce1ars User (application) register save area
ebx000-ebx103
ebxsw1-ebxsw7
Application interprogram work area 2
ce1usa User area

Linking ECBs and Their Common Services

The TPF system uses the first 8 bytes of the ECB to link together ECBs requesting the same service, and for the branch address of the system processing routine when the ECB is activated.

Work Areas

Application and design requirements determine the use and format of these areas. You may use the work areas for switches, indicators, and other temporary storage needs unique to each processing program segment, or for passing information from program to program. You can make your application programming easier if each application program in the processing chain specifies in its documentation how each work area will be used.

The work areas must be shared by all programs processing the entry. Two important design considerations for creating a TPF application are to assure a workable protocol and an optimum use of the space for data that must be saved or passed along.

You can use the following ECB work areas for application programming:

Application Work Areas

There are two application work areas, each 112 bytes long, consisting of a 104-byte scratch area followed by an 8-byte bit-switch area.

The first work area begins at ebw000. Each byte of its scratch area is named sequentially beginning with ebw000 and ending with ebw103. The second work area begins at ebx000. Each byte of its scratch area is named sequentially beginning with ebx000 and ending with ebx103.

The last 8 bytes in each of these work areas are intended for use as program switches. The program switch names and their standard usage conventions are as follows:

First work area:

Name
Usage Convention

 ebsw01-ebsw03 
Interprogram switch to specify various conditions among programs

 ebrs01 
Used to pass error information among program segments

 ebcm01-ebcm03 
Intraprogram switch to specify various conditions within programs

 eber01 
Used to pass error information within program segments.

Second work area:

Name
Usage Convention

 ebxsw1-ebxsw7 
No convention.

These conventions are recommended. However, applications not requiring this logic are free to use these bytes in any way desired.

OPZERO initializes the switches--that is, the last eight elements--in both work areas, to zero when it creates the ECB. The first 104 elements of the work areas are not initialized, so their contents are unpredictable. (COMM SOURCE will later place the routing control parameter list, occupying at least 12 bytes, at the beginning of the interprogram work area. See Routing Control Parameter List for further information.)

User Work Area

The user work area is 2752 bytes long and begins at ce1usa as listed in Table 1.

User Application Register Save Area

The user application register save area is for saving registers in assembler application programming. It begins at ce1ars and is 10 fullwords long (registers 14 and 15 and registers 0 through 7).

Data Levels

Each entry has the capability of referencing 16 data blocks concurrently in the ECB. The ECB maintains these references in sixteen data levels numbered hexadecimally from 0 to F (often referred to as D0-DF). As used by the TPF system, the term data level does not imply any priority assigned to the level number or any nesting. A data level is simply a series of doubleword reference/control fields for data blocks that can be used however the application requirements dictate.

There are three sets of doubleword references for each data level. They are, in order of their physical position in the ECB:

The FARWs and CBRWs are of primary importance to your application.

Core Block Reference Words

There is an 8-byte core block reference word (CBRW) for each data level, each of which the C language treats as a pointer followed by two unsigned short integers. The CBRW is used to store the main storage address and control information about main storage blocks used by the entry. TPF system programs format the CBRW whenever a main storage block is attached to or detached from the ECB. The format consists of the main storage address (4 bytes), the block type indicator (2 bytes), and the block byte count (2 bytes). The main storage block address has the same label as the CBRW. The block type indicator and the block byte count have their own labels. In the following example, x is the data level number, a hexadecimal digit from 0 to F.

The block type indicator (ce1ctx) specifies the size of the block attached to the ECB at level x.

    0001          No block attached
    0011          127-byte block attached    (L0)
    0021          381-byte block attached    (L1)
    0031          1055-byte block attached   (L2)
    0051          4095-byte block attached   (L4)

The block byte count (ce1ccx) specifies the number of bytes in the block that the program can access.

It is important to note that only the block type indicator accurately reflects the status of the level at any given time. If ce1ctx contains X'0001', then the data in the rest of the CBRW for level x is not meaningful. TPF does not initialize ce1crx and ce1ccx after a block is released. Only if ce1ctx contains X'0011', X'0021', X'0031' or X'0051' is a currently valid main storage address in the level x CBRW.

TPF updates the CBRW as a result of an application request to obtain or release a main storage block or to read or write a file record. Application programs must never modify the CBRW, but may refer to it to determine data level status and the address of the acquired block.

File Address Reference Words

There is an 8-byte file address reference word (FARW) for each ECB data level, each of which the C language treats as an unsigned long integer followed by four unsigned characters. The FARW is used to record the file address and control data related to file I/O for each data level. There may be a main storage block on a given level without any file activity, in which case the FARW will not be used. When there is file activity the FARW will be used for the record identification (2 bytes), record code check (1 byte), and symbolic file address (4 bytes); 1 byte is unused. In the following example, y is the data level number, a hexadecimal digit from 0 to F.

Example:

When the application program requests TPF, via a macro or a library function call, to read or write a record, the FARW at the specified data level must be set up as described in File Storage Access.

File Address Extension Words

The file address extension word (FAXW) is used to pass information between TPF online systems and MVS, using DASD files called general data sets. See TPF Database Reference for more information about the format and use of the FAXW.

Data Event Control Blocks

You can use data event control blocks (DECBs) as an alternative to using standard ECB data level information. ECB data level information is used to specify information about I/O request CBRW, FARW, and FAXW fields. Although a DECB does not physically reside in an ECB, the DECB fields specify the same information without requiring the use of a data level in the ECB. All the same requirements and conditions that apply to the CBRW, FARW, and FAXW fields in the ECB also pertain to the same field information in the DECB.

Figure 4 shows the DECB application area and the fields inside the DECB:

Figure 4. DECB Application Area


DECB Fields

The DECB fields are used as follows:

 IDECNAM 
Contains the name of the DECB.

 IDECCRW 
Corresponds to an ECB core block level.

 IDECDAD   (Core block) 
Contains the address of a core block.

 IDECCT0   (Type) 
Contains the core block type indicator or X'0001' to signify there is no core block attached.

 IDECDLH   (Len) 
Contains the data length.

 IDECFRW 
Corresponds to an ECB FARW.

 IDECRID   (RID) 
Contains the record ID for a FIND/FILE request.

 IDECRCC   (RCC) 
Contains the record code check (RCC) value for a FIND/FILE request.

 IDECFA   (File Address) 
Contains the file address for a FIND/FILE request.

 IDECSUD 
When the FIND/FILE request is completed, this field will be set to the SUD error value or zero if there is no error.

 IDECDET 
Contains the number of core blocks currently detached from this DECB.

 IDECFX0 
Contains the FAXW information.

 IDECUSR 
Contains the user data.

8-Byte File Address Support

Although an ECB data level and a DECB are alike, there is a difference in the FARW. The IDECFA field, which contains the file address, has been expanded to 8 bytes in the DECB. This expansion allows 8-byte file addressing in either 4x4 format or FARF6 mode. 4x4 format provides for standard 4-byte file addresses (FARF3, FARF4, and FARF5) to be stored in an 8-byte field. FARF6 is the exploitation of 7 of the 8 bytes in the file address.

A 4-byte file address in 4x4 format resides in the low-order 4 bytes of the IDECFA field. The high-order 4 bytes of the IDECFA field contain an indicator (a fullword of zeros) that classifies it as a valid 4x4 format address. The high-order 4 bytes of a FARF6 file address is a nonzero value. When there is file activity, the FARW will be used for the record identification (2 bytes), record code check (1 byte), and a symbolic file address (8 bytes); 1 byte is unused. For example:



Referencing Data Blocks

As previously discussed in Data Levels, data levels can reference 16 data blocks concurrently in the ECB. If you choose to use DECBs, you are not restricted to 16 data blocks. DECBs can be acquired dynamically by a single ECB by using the tpf_decb_create function or the DECBC macro. The storage, which will hold the DECB, comes from the 1-MB private area of the ECB. Therefore, the number of DECBs that the ECB is restricted to is limited only by the amount of storage in the private area that is dedicated to the DECB. See the TPF C/C++ Language Support User's Guide for more information about the tpf_decb_create function and TPF General Macros for more information about the DECBC macro.

Using Symbolic Names

Using DECBs allows you to associate symbolic names with each DECB. This allows different components of a program to easily pass information in core blocks attached to a DECB. Each component only needs to know the name of the DECB where the information is to be found to access it. However, functions that support the use of a DECB (such as file_record_ext, find_record_ext, and so on) will only accept a DECB address as a valid reference to a DECB. If an application does not maintain the address of a particular DECB and, instead, maintains the name of the DECB, the caller will first have to issue the tpf_decb_locate function to obtain the address of the DECB. The resulting DECB address can then be passed on the subsequent function call.

Accessing File Records with a DECB

All types of applications can use DECBs. Application programming interfaces (APIs) have been added to allow TPF programs to access file records with a DECB instead of an ECB data level. However, only a subset of the existing macros and C functions that currently reference ECB data levels accept a DECB in place of an ECB data level. Macros and C functions that use a file address will first verify that it is a valid address in 4x4 format or FARF6 mode. If the address is not valid, a system error will occur. See TPF General Macros and TPF System Macros for more information about general and system macros that were added or changed for TPF DECB support.

Applications that call the following functions (using 8-byte file addresses or DECBs in place of ECB data levels) must be compiled with the C++ compiler and they must create linkage to the service routines in the CTAD dynamic link library (DLL):

New or existing applications that only use ECB data levels can still use the C compiler to create linkage to these TPF functions in the CTAL DLL. See the TPF C/C++ Language Support User's Guide for more information about these functions.

Error Handling

With TPF DECB support, each DECB has a detailed error indicator byte (IDECSUD). The existing ce1sug byte will include any errors that occur on a DECB-related I/O operation.

Functional Flow

The flow of a DECB through the TPF 4.1 system can be very different depending on how it is used by the application. The DECB acts as an interface between the application and the TPF control program, and contains relevant information about core block and file I/O requests. The following example shows how TPF DECB support works by providing a sample application and describing how DECBs are referenced by the TPF 4.1 system.

Assume there is a TPF application called Bermuda. When an airline passenger purchases a one-way ticket to the island of Bermuda, this application is activated to update a database that maintains a list of every one-way passenger. The Bermuda application consists of two program segments, SUNN and SAND. The SUNN segment will validate the database update request and verify that the passenger record does not already exist in the current passenger list. Once the request has been validated, SUNN will forward the request to the SAND segment, which will add the name of the new passenger (A. Traveller) to the existing passenger list.

  1. SUNN is entered by a reservation application with a copy of the passenger record of A. Traveller attached on data level 0 (D0) of the ECB. After verifying that there is a passenger record attached to D0, SUNN allocates a DECB, which will be used to hold the primary database record for Bermuda. The following example shows the DECB allocation:
    Assembler:   IDECB REG=R1
                 DECBC FUNC=CREATE,DECB=(R1),NAME=DECBPRIME
                 ...
                 DECBPRIME DC CL16'BERMUDA.PRI'
     
    C++:         TPF_DECB	*decb;
                 DECBC_RC	rc;
                 ...
                 decb = tpf_decb_create ("BERMUDA.PRI", &rc;);
    
    Because there were no DECBs previously associated with this entry, a 4-K frame will be obtained from the ECB private area, which becomes a DECB frame. Multiple DECBs will be carved from a single DECB frame. The address of the first DECB frame will be stored in page 2 of the ECB in the CE2DECBPT field. It is also possible to have a single ECB with more than one DECB frame. Each successive DECB frame will be forward-chained from the previous frame.



  2. Now that a DECB is available for use, SUNN will attempt to calculate the file address of the primary record for the Bermuda database. The following example shows a call to the file address compute program (FACE) to determine the correct file address:
    Assembler: IFAC8 REG=R7
               LA	R7,EBX000
               MVC	IFACORD,=XL8'150'
               MVC	IFACREC,=CL8'#BERMUDA'
               MVI	IFACTYP,IFACFCS
               FAC8C PARMS=(R7)
     
    C++:      TPF_FAC8	*fac8_parms;
              ...
              fac8_parms = (TPF_FAC8 *)&ecbptr()->ebx000;
              fac8_parms->ifacord = 0x150;
              memcpy (fac8_parms->ifacrec, "#BERMUDA", 8);
              fac8_parms->ifactyp = IFAC8FCS
              tpf_fac8c (fac8_parms);
    
  3. SUNN now has the file address for the primary record and will issue a FIND request to bring the record into working storage and obtain an exclusive lock of the record for this ECB. The following example shows how the FIND-type call might look:
    Assembler: MVC IDECFA,IFACADR
               MVC IDECRID,=CL2'AB'
               XC  IDECRCC,IDECRCC
               FIWHC ,DECB=(R1),ERROR_BRANCH
     
    C++:       decb->fa = fac8_parms->ifacadr;
               find_record_ext (decb, NULL, "AB", '\0'
                                HOLD_WAIT, FIND_DEFEXT);
    
  4. When the FIND request ends either successfully or unsuccessfully, the DECB will be updated accordingly. For a successful call, the SUD value in the DECB will be cleared and a core block will be attached at the CBRW of the DECB.



  5. Now that the primary record has been read in from the database, SUNN enters segment SAND to complete the processing. SAND will search the primary record for an available entry slot to which the passenger record of A. Traveller can be added. If there are no available entries in the primary record, an overflow record will be obtained. To obtain the overflow record, a new DECB must be created. The following example shows the allocation of a new DECB:
     Assembler:  DECBC FUNC=CREATE,DECB=(R2),NAME=DECBOFLW
                 ...
                 DECBPRIME DC CL16'BERMUDA.PRI'
                 DECBOFLW DC CL16'BERMUDA.OVR'
     
     C++:        TPF_DECB *prime, *overflow;
                 DECBC_RC rc;
                 ...
                 overflow = tpf_decb_create ("BERMUDA.OVR", &rc);
    
    The first available DECB in the DECB frame is dispensed to the application. There are now two DECBs in the single DECB frame, which are marked as in use by the ECB.



  6. SAND must obtain a file pool record, which will serve as the new overflow record in the Bermuda database. SAND must then locate the DECB created by SUNN, which contains the primary record so that the pool record can be chained to it. The following example shows how the file pool record is obtained and how the DECB containing the primary record is located:
     Assembler:  GETFC ,DECB=(R2),ID=CL2'AB',BLOCK=NO
                 DECBC FUNC=LOCATE,DECB=(R3),NAME=DECBPRIME
                 ...
                 DECBPRIME DC CL16'BERMUDA.PRI'
                 DECBOFLW DC CL16'BERMUDA.OVR'
     
     C++:        TPF_FA8 pool_addr;
                 ...
                 pool_addr = getfc (overflow, GETFC_TYPE0, "AB",
                                    GETFC_NOBLOCK, GETFC_SERRC);
                 prime = tpf_decb_locate ("BERMUDA.PRI", &rc); 
    
  7. To build the overflow record, SAND must get a core block and attach it to the DECB where the overflow pool file address was obtained. The following example shows a call to the get core routine:
    Assembler:  GETCC ,DECB=(R2),L4,FILL=00
     
    C++:        getcc (overflow,
                      (enum t_getfmt)(GETCC_TYPE+GETCC_FILL),
                       L4, 0x00);                             
    



  8. SAND must now copy the relevant information from the passenger record of A. Traveller, which is attached on ECB data level D0 to an available entry in the overflow record attached to the DECB. After copying the information, a FILE macro request must be issued to update the Bermuda database with the information of the new passenger. The following example shows the FILE request:
    Assembler:  FILEC DECB=(R2)
     
    C++:        file_record_ext (overflow, NULL, "AB", '\0'
                                 NOHOLD, FILE_DEFEXT);
                                                             
    
  9. Now that the overflow record is no longer being referenced by the ECB, SAND may choose to release the DECB that was allocated to hold the record. The following example shows the call to release the DECB, which once held the new overflow record of the Bermuda database:
    Assembler:  DECBC FUNC=RELEASE,DECB=(R2)
     
    C++:        tpf_decb_release (overflow) 
    



  10. Having filed down the updated overflow record, the SAND segment can now update the primary record with the file address of the overflow record to chain them together. After performing this update, SAND can now issue a FILE request to update the primary record in the database and release the lock, which SUNN had previously obtained on the record. The following example shows this FILE request:
     Assembler:  FILUC DECB=(R3)
     
     C++:        file_record_ext (prime, NULL, "AB", '\0',
                                  UNHOLD, FILE_DEFEXT);    
    



  11. After performing its final operation on the Bermuda database, SAND may choose to release the final DECB, which was being used before exiting the ECB. Even if the final DECB is released by the application, the DECB frame will remain attached to the ECB in preparation for when the next DECB will be created. The DECB frame will be released when the ECB is finally exited.
    Assembler:  DECBC FUNC=RELEASE,NAME=DECBPRIME
                ...
                DECBPRIME DC CL16'BERMUDA.PRI'
                DECBOFLW DC CL16'BERMUDA.OVR'
     
     C++:       tpf_decb_release ("BERMUDA.PRI");
    



I/O-Associated Unusual Conditions

Two fields in the ECB are used to indicate unusual conditions associated with I/O requests:

The application should never clear or modify ce1sug, and should only modify ce1sud immediately after an I/O request has ended. TPF resets ce1sug and ce1sud after each waitc function call.

TPF General Macros discusses these indicators in detail.

Note:
See Error Handling for information about unusual conditions for DECBs.

Areas Used by the TPF system

Some areas of the ECB are used exclusively by the TPF system, but can be useful in error analysis. More about error analysis can be found in TPF Program Development Support Reference as well as TPF Testing Environment for Assembly Language in this publication.

TPF Register Save Area

The primary function of the TPF register save area is to save registers 14, 15, and 0 through 7 (the general application use registers) plus register 8 (the application program base register) whenever the application program surrenders control by issuing a control program macro. When control is returned to the application program, the registers are restored from this area.

A main storage dump shows the contents of the registers at the time of the last control program macro, which can be helpful in pinpointing the section of code that was processing at that time.

Control Program Save Area

TPF saves the program status word whenever the operational program surrenders control as a result of a wait type function, and restores it from this area when that program regains control. This area contains pertinent information associated with the application state.

User Register Save Area

The user register save area, which is also known as the application register save area, generally is used in assembler application programming to save register contents when they are being passed between programs. The user register save area is distinct from the TPF register save area.