The RENT option supports constructed reentrancy for C programs
with writable static and external variables. This makes Metal C programs
with writable static and external variables to be reentrant so a program
can be concurrently used by multiple users. The writable static area
(WSA) can be managed by user provided routines. Using the RENT support,
you can use Metal C as an alternative to assembler, to write programs
to run in CICS® environment.
For information about how the CICS API
and the CICS XPI can be used
in Metal C and for programming examples, see
CICS programming interface examples. The default of the RENT
option is NORENT.
Note: The Metal C RENT support is independent of
and different from the NOMETAL RENT support. They should not be mixed.
Example
xlc -qMETAL -qRENT -S a.c 1
as -mgoff a.s 2
export _LD_SYSLIB="//'CBC.SCCNOBJ'" 3
ld a.o
Notes: - Request Metal C RENT support.
- The HLASM GOFF option is required to assemble the compiler generated
code for RENT.
- It is necessary to add CBC.SCCNOBJ dataset to the binder SYSLIB
for the resolution of CCNZINIT and CCNZTERM.
Linkage convention
General
Purpose Register 0 (GPR0) is used to pass the WSA address. The prolog
code you supplied needs to preserve the content of GPR0 on exit of
the prolog code. Programs compiled with RENT and NORENT can be mixed
as long as the NORENT programs do not call RENT programs.
Note: Global
variables compiled with RENT and NORENT cannot have the same name.
Assembler code interface
The
runtime RENT support is accomplished by additional calls generated
for the function
"main" between the prolog/epilog
code and the function code. The RENT environment initialization and
termination routines are called to establish and terminate the dynamically
allocated WSA storage with the static initialization data applied.
For the AMODE 31
"main" function, CCNZINIT and CCNZTERM
are the names of these routines. While for the AMODE 64
"main" function,
CCNZQINI and CCNZQTRM are the function names. For the simplicity of
further references, only the names of the 31-bit version are used.
The actual WSA storage management is done by user supplied plug-in
routines called from CCNZINIT and CCNZTERM. Two user modifiable Global
Set Symbols, &CCN_WSA_INIT and &CCN_WSA_TERM, can be used
in the user supplied prolog code to set the user supplied WSA initialization
and termination function names. The AMODE of the user supplied routines
has to be the same as the AMODE of function
"main".
Note: CCNZINIT,
CCNZTERM, CCNZWSAI and CCNZWSAT require the stack space to be supplied
by function "main" prolog code. Both CCNZINIT and
CCNZTERM require NAB to be established by function "main".
Also, CCNZINIT and CCNZTERM assume stack space to be available for
the WSA initialization and termination functions. This arrangement
is to ensure that the stack space used by CCNZINIT and CCNZTERM as
well as the WSA initialization and termination routines is consistent
with the stack space used by function "main". Allocating
1K of extra stack space (in addition to the DSA size suggested by &CCN_DSASZ
for "main") by function "main" should
be sufficient for AMODE 31. For AMODE 64, the extra stack space is
roughly doubled.
The following new Global Set Symbols
are introduced for the RENT option.
- &CCN_MAIN
- &CCN_RENT
- &CCN_WSA_INIT
- &CCN_WSA_TERM
For detailed information about these new Global Set Symbols,
see
Compiler-generated global SET symbols.
You
can provide your own WSA initialization and termination routines by
setting these Global Set Symbols with the module names of your own
routines. For example:
GBLC &CCN_WSA_INIT
GBLC &CCN_WSA_TERM
&CCN_WSA_INIT SETC 'MYWSAI'
&CCN_WSA_TERM SETC 'MYWSAT'
Your own WSA initialization
and termination routines can be object modules, load modules, or program
modules, and they need to be supplied to the binder's input.
The
compiler generated code for
"main" has the following
kind of assembly statements in it:
WSA initialization routine
Given
the size of the WSA for the whole application and the image of the
WSA with initialization data applied, the WSA initialization routine
you provided dynamically allocate the WSA storage for the application
and copy the WSA image into it. The address of the allocated storage
is returned which CCNZINIT saves it on the function main's stack to
be propagated to the rest of the application. You are responsible
for ensuring that the allocated storage is addressable to all parts
of the application. This particularly means if there are AMODE 31
parts in the application, the WSA storage should not be allocated
above the 2G bar if the AMODE 31 parts need to access it. Also, the
WSA storage has to be allocated in the primary address space. WSA
storage in data spaces is not supported.
The routine you provide
is given an address of an area to store whatever extra information
you want to keep and pass to the WSA termination routine you provided.
The storage area size is the size of a pointer, that is, 4 bytes for
AMODE 31, and 8 bytes for AMODE 64.
- Function prototype:
-
typedef void * (init_func_t) (void * wsa_image_addr,
unsigned long wsa_size, void * *user_info_addr, unsigned int alignment);
- Input parameters:
-
- wsa_image_addr - the address of the WSA image in the loaded program
object
- wsa_size - the total size of the application's WSA
- user_info_addr - the address of the CCNZINIT provided save area
for saving user information
- alignment - the minimum required alignment of the allocated WSA
storage. For example, "alignment=8" means double-word alignment.
- Return value:
- The address of the allocated and initialized WSA storage. The
default is the IBM® supplied
routine CCNZWSAI or CCNZQWSI, which allocates storage for both AMODE
31 and AMODE 64 with the following macro:
STORAGE OBTAIN,LENGTH=(n),BNDRY=PAGE
WSA termination routine
This
routine is called from CCNZTERM for the WSA termination and cleanup
process. It is passed in the address of the WSA storage allocated
by the WSA initialization routine. It is also given the same WSA size
that was originally passed to the WSA initialization routine.
- Function prototype:
-
typedef void (term_func_t) (void * allocated_wsa_addr,
unsigned long wsa_size, void * user_info_addr);
- Input parameters:
-
- allocated_wsa_addr - the address of the allocated WSA storage
- wsa_size - the total size of the application's WSA
- user_info_addr - the saved user information
- Return value:
- The default is the IBM supplied
routine CCNZWSAT or CCNZQWST, which frees the storage with the following
macro:
STORAGE RELEASE,LENGTH=(n),ADDR=(m)