gtpa2m3aApplication Programming

Transferring Processor Control

At times, several programs are required to process a single message. This can be done under the control of a single ECB, or the active ECB can create another independent entry, which has the effect of subdividing the processing. The active entry also has the ability to change the processing order by suspending its own processing or lowering its priority.

Enter/Back Services

Application programs transfer control to other entry points that use the same ECB with the enter/back services. The enter/back mechanism allows the application program to call or return to other application programs. The enter/back mechanism generates a code expansion that contains the information required by the linkage editor to create the linkage to reach the appropriate system service routine. The TPF system locates the programs in system storage and manages the main storage required to execute the programs. In assembler, only the 4-character program library name (for example, CYYA) is needed to call other programs. As programs return, main storage can be released by the system.

Information necessary to locate and execute an application program is transferred through one of the program Enter macros. Enter macros are coded explicitly by assembly language programs. The action of the ENTRC macro is performed automatically by the C language calling mechanism, so there is no C language equivalent of the ENTRC macro. There is a C function that corresponds to the ENTDC (Enter-Drop) macro. A request can be to:

The process of calling a chain of application programs under the control of the same ECB (using the enter/back services) is called nesting. The ECB contains 35 program levels that TPF uses to control program linkage. If more than 35 levels are required, TPF uses an additional block of working storage to control program linkages and correlate the ECB and the programs that it references. This linkage is transparent to the application program. However, the application programs must not exceed the nesting limit determined at system initialization. If the limit is exceeded, a system error will result and the entry will be exited.

You should release all programs as soon as possible to allow efficient use of main storage. This is the significance of the ENTDC macro or the entdc function. When the logic flow indicates that a series of programs no longer need to be activated, you can use entdc to release them. The ENTDC macro or the entdc function handles situations in which a programmer wishes to leave the C programming environment for the assembler environment. For ISO-C after a call to entdc, the stack pointer is reset to the top of the stack and the static storage is kept. For TARGET(TPF) after a call to entdc, all associated stack storage and static storage are released.

The C language programmer who also is experienced in assembler programming under TPF should note that the ENTNC assembler macro is not supported for C programming because a goto concept to an entry point does not exist in the C language.

Create Macros and Functions

Sometimes it is desirable to subdivide the processing of a given message to enable faster response to time-dependent functions or a more efficient program structure. TPF provides a set of macros and functions to permit an active entry to create another independent entry (TPF normally creates an entry as the result of an input message). When tpf_cresc is used, one creating entry can pass as much as 4 K bytes of data to a created entry and the created entry can pass a return value back to the creating entry. The creating entry can pass up to 104 bytes of parameter information to the created entry. Once TPF creates the entry, it retains the name of the creating entry at ECB location ce1trc, but that is the extent of any linkage between the 2 entries--they continue processing completely independently of one another.

TPF stores the parameters to be passed to the created entry in an interim main storage block that it adds as an item to a CPU loop list. This list is one of the following:

TPF dispatches these lists, among others, whenever it is given control. The dispatching is in the above order; therefore, no item on the deferred list can be processed unless the input list is completely empty, and no item on the input list can be processed unless the ready list is completely empty.

When the item placed on the list by the create function is removed from the list for execution, the parameters to be passed to the newly created entry are moved into a new ECB that operational program zero (OPZERO) creates. An ECB is created for each new entry in the system and is assigned an activation number, which is obtained either from a system counter in OPZERO or from the ECB of the program executing the create function. The activation number determines which version of the E-type program the ECB will use. TPF then transfers control to the entry point specified in the create function call.

The type of create function called determines the priority of the processing that will be associated with the new ECB. Table 21 describes the create functions available to programmers using the C language under TPF.

Table 21. Description of Create Functions

Function Action
credc Creates a deferred entry and places the entry on the deferred list.
creec Creates an entry with an attached main storage block, for immediate or deferred processing.
cremc Creates an entry for immediate processing on the ready list.
cretc Creates a time-initiated entry from an item placed on the ready list after a specified time interval. This function requires an interface with the system clocks.
cretc_level Creates a time-initiated entry from an item placed on the ready list after a specified time interval. It places the entry on the specified core block reference word. This function requires an interface with the system clocks.
crexc Creates a low priority deferred entry from the deferred list. This function is like credc, but crexc requires that more main storage blocks be available for real-time processing before it will execute. Programs that create many deferred entries use crexc to avoid depleting the number of blocks available for more critical real-time processing.
sipcc In a loosely coupled environment, provides communication between processors; in a tightly coupled environment, provides communication between instruction streams. This is for system programs only.
swisc_create Creates a new ECB on another I-stream.
system Creates a synchronous entry for immediate processing of a program that has a main function and suspends the current entry.
tpf_cresc Creates a synchronous entry for immediate processing on the ready list and suspends the current entry.
tpf_fork Creates an asynchronous ECB on a specified I-stream.

All these functions subdivide the processing of a given entry by creating a new ECB and passing it to a specified entry point to continue processing. The entry point must have been allocated by means of the system allocator. The proper linkage also must be available to the entry point.

In assembly language, the program to be activated must be specified in the macro instruction operand. R14 and R15 must be used to reference the parameters being passed. For CREDC, CREEC, CREMC, and CREXC, R14 must be loaded with the number of bytes of parameters being passed, and R15 with the location of the parameters. For CRETC, R14 can be loaded with the time interval prior to activation or the time interval can be passed via the TIMEINC parameter of the CRETC macro. R15 contains data to be passed, or the PARM parameter can be used in the CRETC call. See the TPF General Macros for further details on using CRETC parameters.

The CRESC macro, which creates a synchronous entry for immediate processing, may request the creation of up to 50 ECBs. The ECBs are created in the same subsystem and subsystem user as the creating ECB (also called the parent ECB) but may be dispatched on any I-stream. The creating ECB may pass up to 4 K of data to each of the created ECBs. The creating ECB is placed on the wait list until the created ECB has completed. Upon exiting, the ECB that was created may pass a return value back to the creating ECB. See TPF General Macros for further details on using tpf_cresc parameters and register specifications.

Examples:

LA    R1,PGM              Name of program to enter
LA    R2,2                I-stream number
LA    R3,DATA             Address of data to pass
LA    R4,20               Number of bytes of data
LA    R5,100              100 second timeout
CRESC PROGRAM=(R1),WAIT=YES,DATA=(R3,R4),IS=(R2),TIMEOUT=(R5),
      RTNLST=(R6)
                          One ECB will be created and dispatched
                          on the I-stream specified by R2.  Twenty
                          bytes of data, beginning at DATA, will be
                          passed. The creating ECB will wait 100 seconds
                          for the created ECB to be completed
                          successfully.  Upon reactivation, the creating
                          ECB can access the value returned by the
                          created ECB using R6.
 
 
LA    R15,EBW020          Address of bytes to pass
CREMC ABCI                Activate program ABCI
 
 
LA    R14,48              Number of bytes passed
LA    R15,EBW020          Address of bytes to pass
CREMC ABCI                Activate program ABCI
 
 
LA    R14,10              Time increment value
L     R15,EBW040          Data meaningful to program ABCI
 
CRETC S,ABCI              Time interval is seconds (may
                          also be 'M' for minutes)
                          Activate program ABCI after 10
                          seconds
 
CRETC S,ABCI,TIMEINC=10,PARM=pgmlabel
                          Time interval will be placed in
                          R14 by the CRETC macro
                          Activate program ABCI after 10
                          seconds
                          Data meaningful to program ABCI at
                          label 'pgmlabel' will be placed in
                          R15 by the CRETC macro

You must supply the following arguments when calling C language functions credc, cremc, and crexc:

length
An integer between 0 and 104 that determines the number of bytes to be passed to the newly created ECB.

parm
A pointer to the parameters to be passed.

segname
A pointer to the entry point to be called.

A creec function call also must specify the data level that contains the working storage block to be passed to the new ECB. A creec function call also must specify an integer value, either DEFERRED or IMMEDIATE priority, to determine the list where the block is to be placed.

For cretc, you must specify the following arguments:

type
One of the predefined terms MINUTES or SECONDS, which indicate the units associated with the specified time interval.

segname
A pointer to the entry point to be called, as above.

units
An integer value that defines an increment of MINUTES or SECONDS that will elapse before the ECB is activated.

action
The address of 4 bytes to be passed to the created ECB. They will be copied into the work area of the new ECB ebw000-ebw003.

A cretc_level function call also must specify the data level of the core block reference word on which the ECB will be placed.

For tpf_cresc, you must specify the following arguments:

program
The name of the program that the created ECB will run.

istream
The number of the I-stream on which the created ECB will run.

wait
For WAIT=NO, initialize the created ECB; for WAIT=YES, create an ECB and dispatch all requested ECBs.

timeout
The number of seconds the creating ECB will wait for the created ECBs to be completed successfully.

rtnlst
The pointer that will contain the address of the event block with the return values of the created ECBs.

Examples of Using the Create Functions:

The following example creates a deferred entry for program COT0, passing the string "VPH" as input data to the program.

  #include <tpfapi.h>
  char *parmstring = "VPH";

  ·
  ·
  ·
credc(strlen(parmstring),parmstring,COT0);

The following example creates an ECB dispatched from the ready list for program OMA0, passing the string "755/15AUG" and the working storage block on level D0 as input to the program.

  #include <tpfapi.h>
  char *parmstring = "755/15AUG";

  ·
  ·
  ·
creec(strlen(parmstring),parmstring,OMA0,D0,IMMEDIATE);

The following example creates an ECB dispatched from the ready list for program COT0, passing the string "VPH" as input data to the program.

  #include <tpfapi.h>
  char *parmstring = "VPH";

  ·
  ·
  ·
cremc(strlen(parmstring),parmstring,COT0);

The following example creates an ECB dispatched from the ready list for program QZZ0 after 5 seconds have elapsed. TPF will place the 4-byte character string "INIT" in ebw000-ebw003 of the new ECB.

  #include <tpfapi.h>

  ·
  ·
  ·
cretc(SECONDS,QZZ0,5,"INIT");

The following example creates a deferred entry for program COT0, passing the string "VPH" as input data to the program.

  #include <tpfapi.h>
  char *parmstring = "VPH";

  ·
  ·
  ·
crexc(strlen(parmstring),parmstring,COT0);

The following example creates two synchronous ECBs for immediate processing. The first ECB that is created will be passed 20 bytes of data and will be dispatched on I-stream 1. The second ECB that is created will not receive any data, will be dispatched on the main I-stream, and the creating ECB will wait indefinitely for the created ECBs to be completed.

 
#include <stdio.h>
#include <stdlib.h>
#include <tpfapi.h>
 
/* Initialize parameters for WAIT=NO call.                          */
 
char data[16] = "Hi..this is QXQZ";    /* Data to be passed         */
 
struct tpf_cresc_input tci;            /* Input structure for       */
                                       /* tpf_cresc()               */
struct tpf_ev0bk_list_data *ebptr;     /* Return value from         */
                                       /* tpf_cresc()               */
 
tci.program = "QPM1A";                 /* Pgm for child to enter    */
tci.istream = 1;                       /* I/S for child to run on   */
tci.wait = TPF_CRESC_WAIT_NO;          /* Don't create ECB yet      */
tci.data_length = 20;                  /* Pass 20 bytes of data     */
tci.data = data;                       /* Pass data at label DATA   */
 
/* Issue WAIT=NO call.                                              */
 
ebptr = tpf_cresc(&tci);              /* Issue WAIT=NO call        * /
 
/* Initialize parameters for WAIT=YES call.                         */
 
tci.program = "QPM1A";                /* Pgm for child to enter     */
tci.istream = TPF_CRESC_IS_MAIN;      /* I/S for child              */
tci.timeout = 0;                      /* Timeout value for parent   */
                                      /* Parent will wait forever   */
tci.wait = TPF_CRESC_WAIT_YES;        /* Create all children        */
tci.data_length = 0;                  /* No data being passed       */
tci.data = NULL;                      /* No data being passed       */
 
 
/* Issue WAIT=YES call. All child ECBs requested to date will now   */
/* be created and dispatched.                                       */
 
ebptr = tpf_cresc(&tci);              /* Issue WAIT=YES call        */
 

Suspend Processing Macros and Functions

TPF provides 2 macros or functions that permit the entry currently using the CPU to request suspension of processing. TPF places suspended entries on either the input or deferred lists. This permits system programs to restore registers and return control to a suspended program.

The 2 functions used to suspend processing are:

Function
Action

 defrc 
Defer Processing of Current Entry -- Places the entry at the bottom of the deferred list. The deferred list is simply the lowest priority list serviced by the CPU loop. After the entry is placed on the deferred list the system will service the higher priority lists.

 dlayc 
Delay Processing of Current Entry -- Places the entry at the bottom of the input list: dlayc is, therefore, a shorter suspension than defrc.

No parameters are required with the defrc and dlayc functions.

The defrc and dlayc functions differ slightly from the waitc function. The waitc function is related to the completion of an I/O operation; if no I/O is pending then no suspension occurs. Both dlayc and defrc place the entry at the bottom of a list.

The period of time during which processing is suspended for deferred entries can be substantial. Accordingly, no records can be held by means of the record hold facility by an entry executing defrc, and no time dependent action (for example, response to a terminal) should follow this function. The entry should hold the least possible amount of working storage to minimize the impact on system performance.

Exit Functions

The exit functions are a special case of transferring control. They signify that processing of the entry is complete, and that the application wishes to release the remaining system resources and return control to TPF. Exit functions do the housekeeping required to remove an entry from the system. Resources held by the exiting entry are returned to the system for use by other entries.

When you call an exit function, the TPF system transfers control to the exit system service routine. Several library functions can cause this transfer of control to occur:

 exit  
Exits the ECB under normal circumstances.

 abort  
Exits the ECB under abnormal circumstances.

 serrc_op  
For C language, when coded with the predefined term SERRCEXIT as its first argument, calls the system error routine and then exits the ECB.

 SERRC  
For assembly language programs using SERRC (or its less expensive counterpart snapc), calls the system error routine and then exits the ECB.

 serrc_op_ext  
This function is similar to the serrc_op function with the addition that a prefix can be specified to identity the user or system program generating the dump.

 snapc  
Generates a snapshot dump and allows the program to stop or continue according to a parameter.

A program check (for example: an addressing exception, or an attempt to change protected areas of main storage) also causes the TPF system to transfer control to the exit system service routine.

Exit System Service Routine

The exit system service routine performs the following checks and functions when executing on behalf of exit, abort, snapc, and serrc_op with the SERRCEXIT option for C language or SERRC for assembly language:

The information needed for clearing an exited entry from the system is contained in various ECB fields.

Calling the Exit Functions

No operands are required with the EXITC macro. The parameters for the SERRC and snapc macros are described in TPF General Macros.

The exit functions for C language require the following arguments:

Function
Arguments

 exit 
An integer value that specifies a return code. In TARGET(TPF) if the value is nonzero, a system error dump bearing this number will be issued prior to exiting.

 abort 
None.

 serrc_op 
Four arguments specified in the following order:
  1. A status argument (predefined to be SERRCEXIT for the purposes described above).
  2. An integer of which the last 24 bits will be the identification number for the dump.
  3. A pointer to the string to be displayed at the CRAS console and appended to the dump (or NULL if no message is desired).
  4. A pointer to an array of pointers that indicates extra areas of storage to be displayed on the dump (or NULL if no storage list exists).

 serrc_op_ext 
The same 4 arguments specified in serrc_op and a prefix argument that associates an error with either an application or the IBM system.

Transfer Vectors

Transfer vectors are not supported for load modules. Load modules contain 1 external entry point.

In TARGET(TPF) C language transfer vectors allow a single program segment to have multiple entry points; in other words, transfer vectors allow a single program segment to contain multiple entry points. TPF handles calls to transfer vectors with the enter/back services: even when transfer vectors in the same program segment call each other. You should be aware of the general form of transfer vectors so that you will recognize them when you see them in existing code.

In TARGET(TPF) transfer vectors are coded into the system allocator and cross referenced to the program segment name. From C programs, transfer vectors can be called in the same way as normal entry points. If a C program contains multiple entry points, these functions are treated as transfer vectors. The IBM C compiler with TARGET(TPF) set automatically generates a branch table consisting of a series of unconditional branch instructions associated with each of the transfer vector names. Each transfer vector, once entered, functions as an independent entry point.