Time is a tough beast to corral. You need time to assign new projects, and then, you need to find the time to actually develop those projects. Of course, you need to make time to complete those projects, too. The use of prewritten modules and procedures that can be easily accessed from the developers program can help reduce the amount of time needed to develop and maintain projects and can make putting a bit in the beasts mouth much easier. In this article, I tell you about a set of procedures I wrote to handle one common function: memory management. Your staff will be able to use this toolkit to help themselves quickly write reusable code without having to understand the complexities of memory management.
The ILE makes it easier for AS/400 programmers to create reusable procedures to be used as building blocks of programs. Toolkits provide the building blocks that support commonly used application tasks. The Storage Toolkit provides tools that make it easier to work with dynamically allocated storage. What is dynamically allocated storage? Dynamically allocated storage allows your applications to be more flexible by making it less likely that you will need to change your applications to accommodate business growth. Storage is allocated as it is needed.
Another advantage of using the Storage Toolkit is that storage can be named. Named storage allows programs to share information without passing parameters. For example, you can use the Storage Toolkit to store a named value, such as default output queue, using the Allocate Named Storage procedure. Programs that need to use this common value simply request it by name using the Retrieve Named Storage procedure. If the named storage is allocated from the local data area (LDA) or a user space, programs running in different activation groups can even share it.
You may have heard that using dynamically allocated storage is dangerous because memory leaks can reduce available system resources. A memory leak is caused when storage is allocated but never deallocated. You can use the logging facility in the memory toolkit to reduce this possibility. When logging is in effect, a message is sent when storage is allocated and deallocated. That way, you can use these messages to identify and correct leaks when you are developing a program.
Types of Storage
The Storage Toolkit supports three types of storage: heap storage, user space storage, and the LDA. Each type of storage has its own advantages and disadvantages. The one you choose depends on whether applications will share the storage, the amount of storage required, and whether submitted jobs will use the value being stored. The type and attributes of allocated storage are set when the storage is allocated and can be changed by deallocating and reallocating the storage.
Heap storage (heaps are associated with jobs and activation groups) is storage allocated from a heap. For this reason, when a job or activation group ends, heap storage is discarded. The AS/400 has two types of heaps: the default heap and user-created heaps. The Storage Toolkit uses the default heap, which RPG IV programs automatically create and maintain when you use the ALLOC, DEALLOC, and REALLOC operation codes. Heap storage can be quite large; it can expand in size to just a little less than 4 GB.
The next type of storage the Storage Toolkit supports is user space storage. User spaces are system objects that can contain up to 16 MB of data. The Storage Toolkit creates user spaces in QTEMP.
The final type of storage the Storage Toolkit supports is the LDA. The LDA is a special data area the system creates when a job starts. The biggest limitation of the LDA is its size, which is only 1024 bytes. For interactive jobs, this area is initially set to blanks. For submitted jobs, the LDAs value is initialized to the value of the submitting jobs LDA. This fact makes the LDA a good choice when information needs to be made available to a submitted job. To display the LDA or use the LDA in a program, specify the special value *LDA for the data area name. When deciding which type of storage to use, you need to determine how much storage is necessary (a little or a lot) and whether the storage will be shared.
Before using storage with the Storage Toolkit, you need to allocate the storage. There are several ways to allocate storage using the Storage Toolkit. You can allocate storage by name or by simply retrieving a pointer to the allocated storage. You can also allocate an array of storage, including an optional header area. Three procedures are provided to allocate storage, which are listed in Figure 1. You can download the source for the listed procedures along with a demonstration program at www.midrangecomputing.com/mc/. The demonstration program, TstStgTkt, shows how to use the Storage Toolkit to allocate different types of storage.
When the Storage Toolkit allocates storage, information describing the storage and a pointer are saved to the allocated storage. The storage allocation procedures also support a logging flag. If this flag is not passed, the default storage logging value is used. When logging is requested, a message is sent when storage is allocated and deallocated. The default storage logging value is stored in data area DftStgLog. A logging value of 1 indicates that allocations and deallocations of storage should be logged. If storage is allocated to a user space, the Storage Toolkit creates the user space if the user space does not exist. The Storage Toolkit also increases the size of the user space as needed when storage is allocated. To allocate storage to a field, use either the Allocate Storage or Allocate Named Storage procedure. The amount of storage to allocate should correspond to the size of the variable that you will use to access the dynamically allocated storage. You can use the %SIZE built-in function to ensure that the allocated size matches the size of this variable. If the storage being allocated will not be shared between programs, you can use the Allocate Storage procedure. This procedure returns a pointer to the allocated storage. This allows you to use the storage without using the Retrieve Named Storage procedure.
To allocate array storage, use the Allocate Named Array Storage procedure. You specify an initial number of elements and an optional increment value. When you specify an increment value and attempt to retrieve an array element that falls outside the current allocation, additional storage is automatically allocated. The Allocate Named Storage
procedure also allows you to set up a heading area for your array. This area typically contains information associated with the array, such as the current element count.
Using the Storage Toolkit
Storage allocated using the Storage Toolkit can be retrieved and sorted using Storage Toolkit procedures. When your program no longer needs storage allocated with the Storage Toolkit, the storage should be deallocated. The procedures that support these functions are the retrieval, deallocation, and sorting procedures summarized in Figure 1.
To retrieve storage allocated by the Storage Toolkit, you need to set up pointer- based variables. When defining a field as based, you specify the Based keyword and supply a basing pointer. The value of a variable defined using the Based keyword is stored at the location pointed to by its basing pointer. The TstStgTkt demonstration procedure contains an example that shows how to define and use based variables.
The Storage Toolkit has three procedures that allow you to retrieve allocated storage. The first is the Retrieve Named Storage procedure. This procedure allows you to retrieve storage by using the name assigned when the storage was allocated. This procedure returns a pointer to the allocated storage. The second procedure is the Retrieve Named Array Storage procedure, which allows you to retrieve a pointer to an array element or an arrays heading area. The third procedure is the Retrieve LDA Storage procedure. This procedure is used by a submitted job to retrieve a pointer to a value that was stored in the LDA by its submitting job using the Allocate Named Storage procedure.
The Storage Toolkit provides support for sorting arrays created by the Allocate Named Array Storage procedure. The Sort Named Array Storage procedure checks to see if the arrays storage is contiguous. If the array is not contiguous, Sort Named Array Storage moves the array to a contiguous block of storage. Sort Named Array Storage then sorts the array using the C library QSORT function. One of the parameters passed to Sort Named Array Storage is a procedure pointer to a user-supplied comparison procedure. The comparison procedure compares two elements of the array and returns a value indicating whether the first element passed to it is less than, equal to, or greater than the second element passed to it. A description of the parameters passed to the user-supplied comparison procedure is contained in the heading description of the Sort Named Array Storage prototype. Look at the UsrSrt procedure in the TstStgTkt module to see an example of a user-supplied comparison procedure.
Keeping Track of Storage
The Storage Toolkit has a user index to store information about allocated storage. A user index allows information to be stored and retrieved using a key. User indexes are similar to keyed database files, but they are a little faster because they have less overhead than a file does. Each entry in a user index can contain up to 2,000 bytes of fixed- or varying-length information. User indexes are created using system APIs. The Storage Toolkit contains a module with procedures to support the user index APIs. These procedures provide an interface to the user index APIs that makes them easier to use.
Putting Away the Toolkit
Software toolkits such as the Storage Toolkit allow programmers to focus on the business problem presented to them rather than on the logic needed to develop common coding tasks. This removes the time-consuming burden of having to reinvent common procedures every time an application is developed. This has the net result of giving your shop a much- needed boost in the area of time management.
AS/400 Information Center: publib.boulder.ibm.com/pubs/html/as400/ic2924/info/index.htm
C Library Reference (SC09-2119-00, CD-ROM QBJATN00)
Procedure Type Description
AlcNamArrStg Allocation Allocates named array storage, including heading area AlcNamStg Allocation Allocates named storage
AlcStg Allocation Allocates storage and returns pointer to storage DlcNamStg Deallocation Deallocates named storage
DlcStg Deallocation Deallocates storage allocated by AlcStg
GetStgLog Logging Retrieves the default storage logging flag
SetStgLog Logging Sets the default storage logging flag
RtvNamStg Retrieval Retrieves a pointer to allocated named storage RtvNamArrStg Retrieval Retrieves a pointer to an array element or array heading area RtvLDAStg Retrieval Retrieves named LDA storage in a submitted job SrtNamArrStg Sort Sorts named array storage using user-supplied procedure AddIdxEnt User index Writes a user index entry
CrtUsrIdx User index Creates a user index
DltUsrIdx User index Deletes a user index
RmvIdxEnt User index Removes a user index entry
RtvIdxEnt User index Retrieves a user index entry
RtvUsrIdxAtt User index Retrieves information about a user index
CrtUsrSpc User space Creates a user space
DltUsrSpc User space Deletes a user space
RtvUsrSpc User space Retrieves a user space
RtvUsrSpcAtt User space Retrieves information about a user space
RtvUsrSpcPtr User space Retrieves a pointer to the beginning of a user spaces data
Figure 1: This is a summary of procedures included with the Storage Toolkit.