gtpa2m0wApplication Programming

Functions and Calling Other Functions

The following tables show summaries of the calls that are supported in TPF E-type programs.

Table 7. Function or Program Calls Allowed in ISO-C

Type of Function (or Program) Originating the Call Dynamic Load Modules (DLMs) DLMs with main External Functions (Link Scope) Library Functions Static Functions (Source Scope) Assembler Programs Dynamic Link Library (DLL)
Dynamic Load Modules (DLMs) Yes Yes Yes2 Yes Yes1 Yes7 Yes3
DLMs with main Yes Yes Yes2 Yes Yes1 Yes Yes
External Functions (link scope) Yes Yes Yes2 Yes Yes1 Yes Yes3
Library Functions Yes Yes Yes2 Yes Yes1 Yes No4
Static Functions (source scope) Yes Yes Yes2 Yes Yes1 Yes Yes3
Assembler Programs Yes6 No Not Applicable No Not Applicable Yes No5
Dynamic Link Library Yes Yes Yes2 Yes Yes1 Yes Yes
Notes:

1 means in the same object file.

2 means in the same load module.

3 means the function or program originating the call must be compiled with the DLL compiler option.

4 Library functions cannot be compiled with the DLL option; therefore, a run-time library function cannot call a DLL.

5 A segment written in assembler cannot call functions in a DLL.

6 A segment written in assembler can call the entry point function in a C++ load module because of the extern "C" wrapper for the entry point function. This wrapper makes the linkage to the entry point of the load module be C linkage.

7 If you want to call a program written in assembler from a program written in C++, you need to put the C function prolog and epilog macros, TMSPC and TMSEC, around the program written in assembler. You also need to prototype the program written in assembler as a C function.

Note:
The parameter list structure and linkage are different between C and C++. Therefore, functions coded in C and compiled with a C compiler cannot call functions written in C++ unless the C++ function is declared to have C-type linkage using extern "C".

See Table 6 and "main or extern "C" Requirement" for more information about this linkage difference.


Table 8. Function or Program Calls Allowed in TARGET(TPF).

Type of Function (or Program) Originating the Call External Functions Library Functions Static Functions Assembler Programs
External Functions Yes Yes Yes * Yes
Library Functions Yes Yes Yes * No
Static Functions Yes Yes Yes * Yes
Assembler Programs Yes No No Yes
Note:
* means in the same module.

There are several different types of items that DLMs can call using function call syntax:

The only difference between calling BAL segments and other C functions is that the function prototype for BAL segments is restricted. If you call a BAL segment, the prototype must be:

    void SEGN(struct TPF_regs *);

where SEGN is the 4-character segment name.

The call to a BAL segment looks like:

    struct TPF_regs regs;
    /* Set up regs as appropriate to the BAL segment interface */
    SEGN(&regs);

In standard C or C++, if the BAL segment does not use registers in its interface, you can code a NULL pointer:

    SEGN(NULL); /* You MUST code the regs parameter for BAL calls,  */
                /* even if the called segment doesn't use registers */
                /* for its interface.                               */

Do not use the NULL pointer instead of TPF registers in TARGET(TPF).

Functions Calling Other Programs

There are several functions that activate only E-type programs. The following functions call E-type programs:

 entdc 
reset stack, no return (drop nesting levels)

 credc 
create new deferred ECB

 creec 
create new ECB with core block attached

 cremc 
create new immediate ECB

 cretc 
create new time-initiated ECB

 cretc_level 
create new time-initiated ECB with core block

 crexc 
create new low-priority deferred ECB

 crosc_entrc 
cross-subsystem call with return

 swisc_create 
create new ECB specifying I-stream

 tpf_cresc 
create new synchronous ECB

 system 
execute a command

If a function is written in assembler with the TMSPC and TMSEC macros, this assembler function can activate E-type programs. The following is a list of the BAL equivalents of the C macros:

 ENTDC 
enter dropping nesting levels (reset ISO-C stack)

 ENTRC 
enter with return

 CREDC 
create new deferred ECB

 CREEC 
create new ECB with core block attached

 CREMC 
create new immediate ECB

 CRESC 
create new synchronous ECBs

 CRETC 
create new time-initiated ECB

 CREXC 
create new low-priority deferred ECB

 CROSC ENTDC 
cross-subsystem ENTDC

 CROSC ENTRC 
cross-subsystem ENTRC

 SWISC ENTER 
cross-I-stream enter (ENTDC)

 SWISC CREATE 
create new ECB specifying I-stream

Notes:

  1. Load modules do not use ENTNC and CROSC ENTNC macros.

  2. For TARGET(TPF), writable static storage is deallocated by entdc. For standard C, writable static storage is preserved across entdc.

ISO-C Linkage Performance Considerations

How ISO-C functions are packaged can affect the overall performance of a program. There are several ways to package functions:

There are advantages and disadvantages to each packaging technique.

INLINE Compiler Option

The fastest performance for a function comes from using the INLINE option of the compiler. Using inline functions eliminates entirely call linkage, function prolog, function epilog and return linkage, and allows global optimization of calculating function arguments and the function body. If simple functions must be called many times in a loop, the combination of inlining and global optimization can yield significant improvements in path length.

Note:
Because there are no references to certain functions with inlining, there are no pointers to them. These functions will not be part of the link map for the load module. See TPF Operations for more information about the ZDMAP command and link map support.

One cost of using inline functions is maintenance. The source code for the functions is included in header files for all the programs that use them. If a function needs to be updated all applications that call it must be recompiled, relinked, and reloaded.

Other disadvantages to inline code are:

Inlining is an optional feature of the IBM C compilers on the System/390 platform. Inlining is standard for the IBM C++ compilers on the System/390 platform. It is not part of the ANSI/ISO C standard.

Linking Functions

The next fastest performance is determined by how functions are accessed, whether through a stub or not. Functions that are accessed without using a stub are faster than those accessed through a stub.

For function calls that do not need a stub, the compiler, linkage editor, and relocating loader (program fetch) generate the linkage, which is executed without use of system services or system data. Call linkage is usually 2 instructions, plus parameter loading and unloading, and return linkage is included in the function epilog.

The cost of a function in the same compiled unit as its caller and the cost of link editing functions together are much the same. It is a tradeoff between program execution and easier maintenance. If a function needs to be updated, only the function itself must be recompiled, but all applications that use the function still must be relinked, reloaded, and tested again.

Using Library Functions

The use of library functions involves a slightly longer path length than the use of link-edited functions. This is because the calling program must use a library call stub to access library functions. In addition, secondary linkage processing makes the path length for the library calls much longer if one of the following conditions exists:

The advantage of library functions is that they are easy to maintain and reuse in many applications. If the function needs to be updated only the function needs to be recompiled, and only the library load module needs to be relinked and loaded.

A disadvantage is that at a given time, for a given library, all functions use the same linkage. Libraries that contain reentrant (RENT) static ALWAYS use secondary linkage. Therefore, library functions that require reentrant static should not be included in libraries that must give high performance.

DLM Performance

DLMs are the primary structure for ISO-C functions. Call and return linkages between DLMs are managed by TPF system services and are comparable to ENTRC and BACKC linkage. There is additional overhead for managing linkages between different types of programs.

The performance decision involves the number of DLMs that need to be created for a given application. The fewer DLM calls needed, the faster a given application performs. Calls to DLMs generate the most linkage overhead because they:

The disadvantage is the loss of visibility of the function of a DLM to the system. If DLM A is folded into DLM B to improve DLM B's performance, the service that DLM A provides is lost to other DLMs (without replicating DLM A).

Run-Time (Nondynamic) Library Function Linkage

Note:
This section discusses library function linkage for run-time (nondynamic) libraries only. See "Dynamic Link Library (DLL) Support" for more information about DLL linkage.

ISO-C uses an array of addresses to library vectors (AOLA) to provide its primary linkage to library functions. See Figure 7. The AOLA is created during TPF restart. AOLA entries are replaced with pointers to library vectors (LIBVECs) as libraries are read into main storage. A LIBVEC is a series of entry point addresses of functions.

Each library is associated with a particular library ordinal, defined by the library interface tool. This library ordinal defines the order that the libraries are placed in the AOLA. See Table 9 to see which ordinals are assigned to which libraries. The AOLA mechanism allows calls to functions in as many as 1024 libraries. A library ordinal in the AOLA and a LIBVEC offset together serve to uniquely identify a particular function.

When a new version of a library included in an E-type loader loadset is activated, a common block is used to build a new AOLA. The common block is key-protected.

Figure 7. Example of an Array of Library Addresses and LIBVECs


Table 9 describes which ordinals are in use by which library.

Table 9. Library Ordinals

Library Ordinal Number Description
CISO 0000 Standard C library
CTAL 0001 TPF API library
CTDF 0002 TPFDF library
CTBX 0003 ISO-C general purpose toolbox library
COMX 0004 TPF communications functions
CMQI 0007 MQI client library
CTHD 0008 threads library
CRPC 0011 RPC library

Function Stubs

Linkage to functions contained in libraries is through a stub. A stub is a small piece of code on the end of a program used to locate functions in libraries. For example, the clock function is contained in the TPF library CISO. Imagine a program BAZ calls clock. To gain access to the clock function, control transfers to the stub for clock on the end of BAZ. The stub was added during the link-editing of BAZ. The stub itself comes from the stub library created by the library interface tool. The stub for clock contains the library ordinal and LIBVEC offset for the actual clock function. The executable form of the clock function was loaded during TPF restart when the CISO library was loaded. The information in the stub provides run-time access to the code for clock and the stub transfers control to the clock code.

Suppose we have a program BAZ. Overall, when the C compiler encounters an external function call (Foo) in an ISO-C program, it generates external function linkage. While satisfying the external linkage, the linkage editor gets a stub to access the external function. (See the Figure 8.)

The address of the function required is not available at compile time. The compiler generates a VCON to be satisfied during linkage editing. During linkage editing the VCON for the external function is satisfied by using the stub function that corresponds to the function called. The linkage editor retrieves the stub from the stub library and appends it on the end of the load module being generated. The stub contains the library ordinal and the LIBVEC offset. When the stub was generated, it was set with information about the location of the function it represents. In the example function Foo is the fourth function defined in library CMAS (301), so the library ordinal is 301 and the LIBVEC offset is 3. When run, the stub function performs like an execution-time "glue module", sticking the library references kept in the function body together with the library as it exists in the online system.

Figure 8. Offline Stub Linkage


When segment BAZ runs on the online system and finds a call to function Foo, the stub for Foo at the end of BAZ uses the library information to locate the executable code for Foo. (See Figure 9) The stub does this by using the library ordinal (301) it contains to look up the pointer to the correct LIBVEC in the AOLA. Using the LIBVEC pointer and the offset (3) it picks up a pointer to the code for Foo (in the CMAS user library). With this LIBVEC the stub uses the function offset to locate the entry point address for function Foo, which was created when the library with Foo was loaded (during restart). The stub transfers to the entry point address to run the Foo function. When Foo returns, it continues at the NSI after the original call to Foo in program BAZ.

It is critical that the order of the libraries in the AOLA must correspond to the order of the libraries used when programs are compiled and linked. Clearly, if the order of the 2 libraries is different, the functions called by the program will not be the functions run by the system.

Figure 9. Online Function Linkage


Secondary Linkage for ISO-C Support

If a library requires writable static, or contains an active user exit, or is selectively activated using the E-type loader, the linkage for any function in the library uses secondary linkage. In this case, the AOLA entry for the library is a pointer to the secondary LIBVEC. The LIBVEC itself points to a branch vector that receives control instead of the function directly. When the function is called, common code handles the static storage pointers or activates the user exit routine. This additional overhead causes slower performance in these functions.

Writable static involves such overhead that you should be clear about what it is. In C language a variable can be declared static. This means the variable is not reinitialized every time the function containing it is called. An example of static data is a constant character string (like "this is a test"). Constant data can be reinitialized with every function call without loss. What if you wanted to prevent the data from being initialized every time? If the static character string contained a part that changed (like "this is Bob", "this is Fred", and so on), something special would be required to keep the information. This something special is secondary linkage. Secondary linkage is required to keep track of Bob one time, Fred the next, and so on.

Secondary linkage is described in Figure 10 following. Function Foo, which is found in segment BAZ, has its associated library information. The stub for Foo, which is the same whether primary or secondary linkage is used, is at the end of BAZ and uses the library information. The AOLA entry either points to the executable code for Foo in the CMAS library (primary linkage) or it points to the library startup code at the beginning of the library (secondary linkage). Every library has library startup code at its beginning. The startup code takes care of some housekeeping chores before and after transferring to function Foo. If the CMAS library contains writable static or has the user exits active, secondary linkage is used instead of primary linkage.

In the figure primary linkage is shown as a simple double arrow and secondary linkage is shown as steps A, B, and C.

If writable static is required, space in the frame is set up to accommodate the static. If the user exits are active, they receive control. When the user exit ends, the startup code transfers to the entry point address of Foo. When Foo ends, it returns to the startup code, which transfers to another user exit, if they are active. When this ends, the startup code returns to segment BAZ which continues with the next sequential instruction after the call to Foo.

Figure 10. Online Stub Linkage