Teraspace Usage Tips
You might encounter the following scenarios as you work with the teraspace storage model. Recommended solutions are provided.
- Scenario 1: You need more than 16 MB of dynamic
storage in a single allocation
Use
_C_TS_malloc
or create your programs so that teraspace will be used for heap storage, as described in Using Teraspace for Storage. - Scenario 2: You need more than 16 MB of shared
memory
Use shared memory (
shmget
) with the teraspace option. - Scenario 3: You need to access large byte-stream
files efficiently
Use memory mapped files (
mmap
).You can access memory-mapped files from any program, but for best performance, use the teraspace storage model and, if your language supports it, the 8-byte pointer data model.
- Scenario 4: You need greater than 16 MB of
contiguous automatic or static storage
Use teraspace storage model.
- Scenario 5: Your application makes heavy use
of space pointers
Use the teraspace storage model and a language that supports the 8-byte pointer data model, to reduce memory footprint and speed up pointer operations.
- Scenario 6: You need to port code from another
system and want to avoid issues that are unique to 16-byte pointer
usage
Use the teraspace storage model and a language that supports the 8-byte pointer data model.
- Scenario 7: You need to use single-level storage
in your teraspace program
Sometimes your only choice is to use single-level storage in your teraspace storage model programs. For example, you might need it to store user data for interprocess communication. You can get single-level storage from any of the following sources:
- Storage in a user space, obtained from the QUSCRTUS API or the CRTS MI instruction
- Single-level storage heap interfaces in your programming language
- Single-level storage reference that was passed to your program
- Single-level storage heap space obtained from the ALCHS MI instruction
- Scenario 8: Take advantage of 8-byte pointers
in your code
Create your module and program with STGMDL(*TERASPACE). Use DTAMDL(*LLP64) or explicit declarations (
__ptr64
) to get 8-byte pointers to refer to teraspace (as opposed to 16-byte pointers pointing into teraspace). Then you will get the advantages listed in Taking Advantage of 8-byte Pointers in Your C and C++ Code. - Scenario 9: Incorporating a
single-level storage model module
You cannot bind a single-level storage module with a teraspace storage model module. If you need to do this, first try to get a version of the module that uses (or inherits) the teraspace storage model, then simply use it as described in Using Teraspace: Best Practices. Otherwise, you have two options:
- Package the module into a separate service program. The service program will use the single-level storage model, so use the approach given in scenario 10, below, to call it.
- Package the module into a separate program. This program will use the single-level storage model. Use the approach outlined in scenario 11, below, to call it.
- Scenario 10: Binding to a single-level storage
model service program
You can bind your teraspace program to a service program that uses single-level storage if the two service programs activate into separate activation groups. You cannot do this if the single-level storage service program specifies the ACTGRP(*CALLER) option.
- Scenario 11: Calling functions that have pointer-to-pointer
parameters
Calls to some functions that have pointer-to-pointer parameters require special handling from modules compiled with the DTMDL(*LLP64 option). Implicit conversions between 8- and 16-byte pointers apply to pointer parameters. They do not apply to the data object pointed to by the pointer parameter, even if that pointer target is also a pointer. For example, the use of a char** interface declared in a header file that asserts the commonly used P128 data model will require some code in modules that are created with data model LLP64. Be sure to pass the address of a 16-byte pointer for this case. Here are some examples:
- In this example, you have created a teraspace storage model program
using 8-byte pointers with the
STGMDL (*TERASPACE) DTAMDL(*LLP64)
options on a create command, such asCRTCMOD
. You now want to pass a pointer to a pointer to a character in an array from your teraspace storage model program to a P128 char** interface. To do so, you must explicitly declare a 16-byte pointer:#pragma datamodel(P128) void func(char **); #pragma datamodel(pop) char myArray[32]; char *_ptr128 myPtr; myPtr = myArray; /* assign address of array to 16-byte pointer */ func(&myPtr); /* pass 16-byte pointer address to the function */
- One commonly used application programming interface (API) with
pointer-to-pointer parameters is iconv. It
expects only 16-byte pointers. Here is part of the header file
for iconv:
The following code calls iconv from a program compiled with the DTAMDL(*LLP64) option:... #pragma datamodel(P128) ... size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); ... #pragma datamodel(pop) ...
You should also be aware that the header file of the Retrieve Pointer to User Space (QUSPTRUS) interface specifies a... iconv_t myCd; size_t myResult; char *_ptr128 myInBuf, myOutBuf; size_t myInLeft, myOutLeft; ... myResult = iconv(myCd, &myInBuf, &myInLeft, &myOutBuf, &myOutLeft); ...
void*
parameter where a pointer to a pointer is actually expected. Be sure to pass the address of a 16-byte pointer for the second operand.
- In this example, you have created a teraspace storage model program
using 8-byte pointers with the
- Scenario 12: Redeclaring functions
Avoid redeclaring functions that are already declared in header files supplied by IBM®. Usually, the local declarations do not have the correct pointer lengths specified. One such commonly used interface is errno, which is implemented as a function call in IBM i.
- Scenario 13: Using data model
*LLP64
with programs and functions that return a pointerIf you are using data model
*LLP64
, look carefully at programs and functions that return a pointer. If the pointer points to single-level storage, its value cannot be correctly assigned to an 8-byte pointer, so clients of these interfaces must maintain the returned value in a 16-byte pointer. One such API is QUSPTRUS. User spaces reside in single-level storage.