Sign in

docs ILE Concepts

Teraspace Usage Tips

Teraspace Usage Tips

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 as CRTCMOD. 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:

      ...
      #pragma datamodel(P128)
      ...
      size_t iconv(iconv_t cd,
                   char     **inbuf,
                   size_t   *inbytesleft,
                   char     **outbuf,
                   size_t   *outbytesleft);
      ...
      #pragma datamodel(pop)
      ...

      The following code calls iconv from a program compiled with the DTAMDL(*LLP64) option:

      ...
      iconv_t myCd;
      size_t myResult;
      char * __ptr128 myInBuf;
      char * __ptr128 myOutBuf;
      size_t myInLeft, myOutLeft;
      ...
      myResult = iconv(myCd, &myInBuf, &myInLeft, &myOutBuf, &myOutLeft);
      ...

      You should also be aware that the header file of the Retrieve Pointer to User Space (QUSPTRUS) interface specifies a 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.

  • 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 pointer

    If 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.