Functional flow

The flow of a DECB through the z/TPF 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 z/TPF control program, and contains relevant information about core block and file I/O requests. The following example shows how z/TPF DECB support works by providing a sample application and describing how DECBs are referenced by the z/TPF system.

Assume there is a z/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 KB block 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.
    Alternate text
  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.
    Alternate text
  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.
    Alternate text
  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);                             
    Alternate text
  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) 
    Alternate text
  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);    
    Alternate text
  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");
    Alternate text