gtpa2m3bApplication Programming

Main Storage Allocation

The TPF system and an ECB see virtual storage as 2 different address spaces: the system virtual memory (SVM) and the ECB virtual memory (EVM). The SVM contains all storage that can be used by a particular I-stream. The EVM contains all memory that can be referenced by an ECB. Each ECB has its own EVM. The layouts of both the SVM and EVM are shown in Figure 39.

In a virtual storage system, main storage is almost synonymous with system virtual memory. Main storage is a critical resource that must be shared by the CP and ECBs. Its organization and efficient use is an important factor in a high performance system.

Part of main storage contains programs and data that are common to all entries and which are permanently resident there. This portion is called fixed storage, and is allocated at system generation.

It typically includes at least:

Another portion of main storage, called working storage, is allocated as 4 KB frames (in the SVM), from which working storage blocks are carved (in the EVM). Working storage is used to store and update data retrieved from file storage and consists of logical and physical blocks (which can be ECB private or shared) and contiguous or heap storage. (Logical block sizes are described in Figure 39.)

It is the responsibility of system designers to allocate main storage areas to provide optimum system performance. The application programmer's concerns are simply to know how to access the fixed application data area and how to get and return working storage blocks.

Figure 39. Virtual Storage Layout


Note:
TPF's virtual address spaces makes it impossible to use a full 2 gigabytes of real memory.

Allocating Working Storage

Working storage is main storage that is allocated from 4-KB frames and attached to entries during their system life. The elements allocated, for example, are used for the following:

The TPF system allocates storage for automatic variables and parameter lists in C language every time you call an external or library function. Much of this is transparent to the application. However, your application program also may need working storage blocks for its own processing. You can reference a limited number of working storage blocks in your application program from fixed locations in the ECB or DECB.

You obtain access to a single working storage block with the getcc function, which places the address of the block on a specified ECB data level or DECB. You can release working storage blocks with the relcc function.

You can obtain access to DECBs by using the tpf_decb types of functions or by using the DECBC macro. For more information about DECBs, see Data Event Control Blocks. For more information about the tpf_decb types of functions or the DECBC macro, see the TPF C/C++ Language Support User's Guide and TPF General Macros, respectively.

You can obtain access to a heap storage block with the malloc function and release the storage with the freec function. The argument used with the relcc function and the two arguments used with the getcc function are an enumerated data type that is defined in the tpfapi.h header. Examples follow.

The following is an example for assembly language.

GETCC D3,L0

This statement requests a 127-byte block on data level 3. TPF system programs will assign one main storage address from the 127-byte pool to the ECB, and will update the CBRW at level 3:

On return from the GETCC macro, register 14 (R14) will also contain the main storage address of the block, which the ECB can now access in the ECB private area. Of course, the ECB must not be holding a block at the specified level when the macro is issued. If it is, a system error will occur and the ECB will be forcibly exited.

The application can also request a 127-byte common block to share with other ECBs using the COMMON= parameter, for example:

GETCC D3,L0,COMMON=YES

The ECB accesses common blocks in the ECB common area (assuming it is properly authorized).

The release main storage macro is used to release blocks, one at a time, when they are no longer needed. For example:

RELCC D3

The block size is not required. TPF will return it to the pool and update the CBRW. After the RELCC request, the level 3 CBRW (see above, after the GETCC) will appear as follows:

Note that only the block type held indicator is modified. The remainder of the CBRW is unchanged. For additional information on use of the CBRW, see Core Block Reference Words.

When using RELCC, a block must be held at the specified level; if not, a system error will occur and the ECB forcibly exited.

The following is a C language example.

  #include <tpfapi.h>
  #include <c$am0sg.h>
  struct am0sg *amsg;              /* pointer to message block */

  ·
  ·
  ·
amsg = getcc(D3,GETCCTYPE,L1); /* attaches a 127-byte block on data

TPF system programs will assign one main storage address from the 127-byte block pool to the ECB, and will update the CBRW at level 3:

The getcc function normally returns a pointer that represents the starting address of the newly obtained working storage block, which the ECB can now access in the ECB private area. Of course, the ECB must not be holding a block at the specified level when the function is called. If so, a system error will occur and the ECB will be forcibly exited.

The relcc function is used to release blocks, one at a time, when they are no longer needed. For example:

  #include <tpfapi.h>

  ·
  ·
  ·
relcc(D3); /* releases the storage block on data lev

The block size is not required. TPF will return the block to the pool and update the CBRW. After the relcc request, the level 3 CBRW (see above, after the getcc function call) will appear as follows:

Note that only the block type held indicator is modified. The remainder of the CBRW is unchanged. For additional information on use of the CBRW, see Core Block Reference Words.

When using relcc, a block must be held at the specified level; if not, a system error will occur and the ECB will be forcibly exited.

Assembly language and C language applications can also request (and release) storage in blocks of varying sizes (greater than 4 KB) from contiguous or heap storage using the MALOC or malloc, CALOC or calloc, RALOC or realloc, and FREEC or free functions. This storage resides in the heap private area, above 16 megabytes.

If the ECB exits with main storage blocks being held, TPF releases them. This is generally the most efficient way to release this storage, assuming that an ordinary amount of system resources are being used.

In the case of reading from and writing to file storage, it is TPF (rather than the application) that manages the working storage blocks. For a file read, TPF gets a block of the proper size, then reads in the file record. For a file write, TPF writes, and may release, the block. A system error will occur if the application attempts a file read into an occupied data level, or attempts to release a block after a file write (assuming that the write was not performed on behalf of a file with no release function).

TPF provides additional functions that combine the allocation of main storage blocks and file retrieval and storage. See Summary of File Reference Functions and Macros, the TPF C/C++ Language Support User's Guide, TPF General Macros, and TPF System Macros for more information.

Application Global Area

The fixed data area called the application global area is of prime importance to the application programmer. Although in practice the TPF system also uses the application global area, it is primarily an application area. The purpose of the area is to provide efficient access for all programs to commonly and often highly accessed data. A detailed discussion of the concepts and format of the global area is given in the TPF System Installation Support Reference.

Figure 40 shows a layout of the application global area. Conceptually, global area 1 and global area 3 are similarly structured protected areas. Each contains a directory, records for common system and application values, and other protected data records. Global area 2 contains nonprotected data records. An extended global area, residing above the 16-MB boundary, also can be specified; its inclusion in the system is optional. The structure of this area is analogous to the primary area. Application programs can take advantage of the greatly extended storage capacities of 31-bit addressing mode, at the same time relieving storage constraints below the 16-MB boundary. Support is provided under TPF for writing application programs in the C language that interact with global areas 1, 2, 3, and their extended areas.

It is important to note that the TPF global areas are used by programs written in both assembler and the C language and that different naming conventions apply.

TPF convention requires that all symbolic names for the global area start with the @ character in assembly language and _ in C language. The remaining characters in the symbol are in lowercase.

Figure 40. Global Storage Allocation for a TPF Basic Subsystem with a Single I-Stream. Terms labeled GL0xx correspond to the names of assembler DSECTs associated with the areas.


Global Directory

A global directory (@GLOBA for global area 1 and @GLOBY for global area 3) is simply a series of pointers, each with a symbolic name, containing the main storage address of each record or record type in the global area.

For assembly language, the GLOBZ macro provides a DSECT and direct addressability via symbolic names for the first 4096 bytes of global area 1 and global area 3. The directory and the common system/application value records must reside in the 4096-byte limit, but the protected resident records need not.

If the item pointed to is a multiple record file, then the pointer refers to the first record of the file. The application must then develop its own logic for stepping through the file. Because global records must be backed up in file storage, the directory item also contains the system file address.

Common Values

Immediately following each directory is a variable number of records that contain the common system and application values. Each field in these records has a unique symbolic name and either can be operated on or indirectly addressed. In assembly language the GLOBZ macro is used. For example, @CFLTN can be a symbolic name for a 4-byte field assigned in a miscellaneous common value global record. After issuing GLOBZ, the program can address @CFLTN with any standard instruction.

Protected Data Records

The protected resident records are pointed to by the directory (@GLOBA), but fields in these records are not defined by GLOBZ. Each resident record type has its own data macro, and the assembly language program addresses it by loading a base register with the pointer from the directory.

C language access to the protected data records in global areas 1 and 3 may be obtained only by means of a pointer returned by the glob function, (see Global Area Functions for C Language). It is the application programmer's responsibility to write a structure to examine the contents of the record itself.

For example, assume that one of the protected resident records is an exception authorization record that has its fields defined in a data macro named EX0AU, and has a pointer in the global directory labeled @ or _. Your program could address the fields in the exception record with the following code:

GLOBZ REGR=R1            Defines global fields and loads base register
EX0AU REG=R2             Assigns register 2 as base for exception record
L     R2,@EXAU           Loads exception record base with pointer from
                           global directory
CLC   EXAU1,EBW020       Example instruction using detail field from
                           exception record data macro
Note:
Your program should not give up control of the processor (by issuing any I/O request, such as FINWC) between reading a global record or field and updating that record or field. If it does, the data that your program reads may have already been updated by another program by the time your program decides to update it.

Maintaining Global Areas

Global areas are maintained either:

This organization affects the techniques that are used when updating the global areas.

When global data in a central processing complex (CPC) exists in common storage, application programs must use appropriate multiprocessing techniques. See the 370/XA Principles of Operation.

When global data must be maintained identically across multiple copies, global synchronization services should be considered. A detailed discussion is given below.

Synchronizing Global Areas

Global synchronization provides an application programmer with a method of coordinating values in main storage among several active I-streams. This need arises when multiple I-streams (processors) in a multiple processor CPC and/or a loosely coupled (LC) complex use a shared global resource. All I-streams in the complex share DASD and have access to all data that reside on that DASD.

In a Multiple Data Base Function system, a global area is defined for each subsystem user (SSU). A global area also is defined for each processor in a CPC and in an LC complex generated with the High Performance Option licensed feature.

Loosely coupled systems allow terminals to be connected to several CPCs, all of which use the same database. Although most of the data required for an input message to be processed exist on shared DASD storage, some of the critical data resides in global main storage. This data must be maintained (as much as possible) concurrently in all processors connected to the network. In other words, the data must be synchronized.

Each program that relies on the most current value of data in a global area must ensure the presence of the most current data in main storage by using a SYNCC synchronization macro if in assembly language, a GLOBALSYNC argument with the global function if in C language, or if in ISO-C the glob_update or glob_sync functions. (See the Global Area Functions for C Language, Synchronization Considerations and the description of the global function or the SYNCC macro in TPF General Macros for more information.)

Keypointing Global Areas

In TPF, certain critical data in main storage is backed up on file. This data is maintained in records called keypoints, and the process of backing them up is called keypointing. Some global data, when it is modified, is not keypointable. All other data must be keypointed whenever it is modified. A C language application programmer using the global function in ISO-C or TARGET(TPF), or glob_keypoint in ISO-C has the option of specifying that keypointing should take place or allowing the decision of whether or not to keypoint data to be handled by the function itself. More details are given in Operation of the Global Functions.

Global Area Macros for Assembly Language

The use of global area macros varies greatly depending on whether you are accessing synchronized or nonsynchronized global records and fields.

GLOBZ
This macro is used for both synchronized and nonsynchronized records and fields.

GLOBZ is an executive macro as well as a data macro. It defines the symbolic labels to be used in addressing data in the first 4096 bytes of global areas 1 and 3. It also loads the base register specified in the instruction with the address of the global area requested. It has options for global area 1 or global area 3 or both, and to specify a field name to be accessed when the global area is not known.

Examples: GLOBZ REGR=R1                   Loads R1 with base of
                                         global area 1
  GLOBZ REGS=R2                           Loads R2 with base
                                         of global area 3
  GLOBZ REGR=R1,FIELD=@CFLTN              Loads R1 with base of
                                         global area containing
                                         the field @CFLTN

GLMOD
This macro used only for nonsynchronized records and fields.

Application global areas 1 and 3 are in protected main storage. Before they can be modified the application program must first issue the GLMOD macro to change the protection key. Global area 1 or global area 3 may be specified as an operand; global area 1 is the default.

FILKW
This macro is used only for nonsynchronized records and fields.

After the global area is modified, the application program must restore the protection key. Until it is restored, the application cannot modify its own ECB or other standard data areas. This is done with a parameter of the file keyword macro, FILKW.

FILKW can also request that critical main storage records be backed up on file. In TPF, these records are called keypoints, and the process of backing them up is called keypointing. Some global records--those that are not modified--are not keypointable. All others must be keypointed whenever they are modified.

FILKW parameters are:

Up to 8 records or fields may be specified in one FILKW statement.

Examples:

FILKW R,@GBLCC                         Restore protection key
                                       and keypoint record
                                       @GBLCC
 
FILKW N,@GBLCC,@GLOBA                  Update keypoint records
                                       specified; do not restore
                                       protection key.
 
FILKW R,@GLOBA,@GLBCC,@CFLTN,FLD=YES   Restore protection key
                                       and keypoint specified
                                       records. At least 1 of
                                       the names specified is
                                       a field in a record.

SYNCC
This macro is used only for synchronized global records and fields.

The SYNCC macro is used to (1) gain exclusive use of a synchronizable global field to update it and (2) notify other processors in the multiple processor complex that the updates have been made. The synchronization macro and its supporting logic in the control program ensure that the most current data is obtained from the global area, and that any updates to a global record or field are refreshed in the main storage of all the loosely-coupled processors.

SYNCC options are:

The order and timing of the options you specify on the SYNCC macro is critical to the operation of your program.

In a loosely-coupled environment the SYNCC macro results in a find-wait-hold on the file record that services the synchronized global field or record. As a result, it prevents other programs on the same processor or any other active processor from accessing the referenced global field or record. To shorten the duration of this "lockout", you should keep the number of instructions executed between the LOCK and the SYNC or UNLOCK options to the minimum number required to perform the updates.

The SYNCC macro issues a supervisor call to refresh main storage from file storage. This is a slow I/O process during which the program that issues the SYNCC does not have control.

Special Coding Considerations

Because the SYNCC macro modifies the protection key, data in working storage cannot be manipulated after SYNCC LOCK has been issued. If you need access to working storage before all global updates are complete, you can use FILKW and GLMOD macros to alter protection keys appropriately. For an example, see the application global area in the TPF System Installation Support Reference.

Global Area Functions for C Language

Before considering the operation of the global functions, an application programmer should follow the programming considerations that apply to using the global functions provided with IBM C language support. An application programmer who intends to access global data in the extended global areas should follow the addressing conventions for those areas. After considering the operation of the global functions, the programmer who intends to employ synchronization techniques should regard the special treatment that applies.

Each of these topics is discussed in more detail below.

Programming Considerations with the Global Functions

It is important to note that the TPF global areas are used by programs written in both assembler and the C language and that different naming conventions apply. TPF convention requires that all symbolic names coded in assembler for the global area begin with the @ character. The C language prohibits the @ character in any identifier; TPF convention calls for an underscore (_) to be used in its place. All remaining characters are specified by convention in lowercase.

Support for the C language requires that all names used to refer to global fields and records be previously defined in the c$globz.h header and also requires that the tpfglbl.h header, which includes c$globz.h, be included in any code that calls the global functions. Each global tag name in the c$globz.h header is assigned a unique 32-bit number that describes:

The c$globz.h header file normally is created at installation time and must be revised every time that the definition or order of items in the global areas change. Because the compiler treats the contents of c$globz.h as constant values, existing C programs that reference global tag names must be recompiled whenever the c$globz.h header is revised.

Sample code that may be helpful in generating the contents of c$globz.h has been provided with the installation tapes. A more complete description of the use of this code is given in the TPF C/C++ Language Support User's Guide.

Operation of the Global Functions

TPF provides 2 C functions for ISO-C or TARGET(TPF) for the application programmer who wants to access data in the global areas: glob and global. The use of global area functions varies greatly depending on whether you are accessing a global record or field. You can use the global function only with a global field and only to operate on that field, which is discussed in more detail below. You can use the glob function with either a global field or record solely to obtain a pointer to the global data. In the case of a global field, glob returns the field address. In the case of a global record, glob returns the record's directory entry address (core/file) indicated by the tag.

Note:
A program should not give up control (by calling an I/O function, such as finwc) between reading and updating a global field. If it does, the data that the program reads may have already been updated by another program by the time the program decides to update it. Use of the locking facility provides additional security when updating synchronizable global fields.

The operation of the global function is determined by the action that is specified as the second argument in the function call. The predefined terms that can be used to specify the global operation to be performed include:

Term
Action

 GLOBALUPDT 
Updates the referenced global field with the value pointed to by a third argument that is required in the function call. Additional operations (keypointing, synchronizing) determined by the field's attributes are performed on the referenced global.

 GLOBALMODF 
Alters the referenced global field with the value pointed to by a third argument required in the function call. No additional keypointing or synchronization are performed on the field.

 GLOBALCOPY 
Copies the contents of the referenced global field to the place in automatic storage pointed to by a third argument required in the function call.

 GLOBALKEY 
Causes keypointing of the referenced global field. A third argument is not required with GLOBALKEY.

 GLOBALLOCK  
Reserves the exclusive use of the referenced global field and forces its main storage copy to be refreshed from the most current file copy. The contents of the field then are copied to automatic storage. The GLOBALLOCK operation maintains a hold on the file copy to prevent simultaneous alterations to the file copy. This results in a hold in the processor's record hold table and a hold at the associated disk control unit. Programs that use GLOBALLOCK should use GLOBALUNLK or GLOBALSYNC as soon as possible to prevent severe system degradation caused when other ECBs are awaiting access to the referenced global field.

 GLOBALUNLK 
Releases exclusive use of a referenced global field without altering it. A third argument is not required with GLOBALUNLK.

 GLOBALSYNC  
Releases exclusive use of a referenced global field and synchronizes the global values across processors in an LC complex. A third argument is not required with GLOBALSYNC.

The GLOBALSYNC operation is used to (1) gain exclusive use of a synchronizable global field to update it and (2) notify other processors in a multiple processor complex that the updates have been made. The synchronization operation and its supporting logic in TPF ensure that the most current data is obtained from the global area, and that any updates to a global field are refreshed in the main storage of all the LC processors.

The GLOBALSYNC operation refreshes the main storage images of modified data in every active processor by (1) copying the data to file storage; (2) informing the other LC processors, via a facility called interprocessor communication (IPC), that the data should be immediately refreshed from that file copy; and (3) informing the other processors in the CPC that their copy of the data must be updated. The SYNC operation releases the hold on the file copy.

ISO-C support provides for manipulating global fields and records with the glob function. The 6 operations available are similar to those available with the global function.

Term
Action

 glob_keypoint 
Keypoint a global field or record

This function causes the keypointing of the specified TPF global field or record. This function performs the equivalent of a GLOUC assembler macro.

 glob_lock 
Lock and access a synchronizable global field or record

This function reserves exclusive write access to the specified TPF global field or record and forces refreshing of the core copy from the most current file copy. This function performs the equivalent of a SYNCC LOCK assembler macro.

 glob_modify 
Modify a global field or record

This function copies the modification data to the specified TPF global field or record.

 glob_sync 
Synchronize a global field or record

This function releases the exclusive use of the specified TPF global field or record, and synchronizes the field or record across processors in a loosely coupled complex. This function performs the equivalent of a SYNCC SYNC assembler macro.

 glob_unlock 
Unlock a global field or record

This function releases the exclusive use of the specified TPF global field or record. This function performs the equivalent of a SYNCC UNLOCK assembler macro.

 glob_update 
Update a global field or record

This function updates data contained in the specified TPF global field or record. If the tag name is synchronizable, the equivalent of a SYNCC SYNC assembler macro is performed to synchronize the global area across the loosely coupled complex; otherwise, if the tagname is keypointable, the equivalent of a GLOUC assembler macro is performed to keypoint the global record specified by tagname (or the record containing the global field).

Synchronization Considerations

The order and timing of the operation you specify for synchronizing a global field is critical to the operation of your program. These considerations are true for assembly language programs, TARGET(TPF) functions, or ISO-C function.

The locking functions (global GLOBALLOCK and glob_lock) result in a find-wait-and-hold (see File Storage Access) on the file record that services the synchronized global field. As a result, if any other entries on the same I-stream or any other active I-stream in the loosely-coupled complex attempt to simultaneously lock the same global field, their request will be queued. Such entries will be able to access the specified global field only after the first entry has released its lock through either an unlocking function (global GLOBALUNLK or glob_unlock) or a synchronizing function (global GLOBALSYNC or glob_sync).

At any given time only 1 ECB may hold the lock for a particular global field. To shorten the duration of this "lockout", keep the number of instructions executed between the locking functions and either the synchronizing or unlocking functions to the minimum number required to perform the updates.

The synchronizing functions (global GLOBALSYNC or glob_sync) issue a supervisor call to refresh main storage from file storage. This is a slow I/O process during which the program that called for the synchronization does not have control.

Examples of Using the Global Functions

In the illustrative process flow introducing the application interfaces, our credit application stored its floor limit, an integer, assigned the symbolic name CFLTN in a global field. It was updated with the value pointed to by amount as follows:

  #include <tpfglbl.h>

  ·
  ·
  ·
global(CFLTN, GLOBALUPDT, &amount);

If a protected resident record in the extended area were an exception authorization record that had its fields defined in a structure named ex0au, and had a pointer in the global directory labeled _exau, a program could examine the fields in the exception record with the following code:

  #include <tpfglbl.h>
  #include <tpfapi.h>
  struct ex0au {

  ·
  ·
  ·
} *@EXAU;
  ·
  ·
  ·
@EXAU = *(struct ex0au **) glob(_exau);
  ·
  ·
  ·

It would be up to the application to know and properly define the structure used above.