Activation groups provide a wonderful way to isolate resources for separate applications on your system. Activation groups let you create artificial partitions that keep your applications from stepping all over each other. That is the good news. The bad news is that it requires a little more management on your part to keep your activation groups separate. And that is what this article is all about.
We are big proponents of ILE, RPG IV, and APIs, and most of our articles discuss these subjects. This article will certainly be no exception. We are going to show you a utility written in RPG IV that uses the QUSLOBJ and QCLRPGMI APIs to identify programs that are included or excluded from an activation group.
IBM designed ILE to provide developers with a way to mix and match disparate languages and methodologies into singular applications. The goal was simple—to allow developers to use the right tool for the right job—but the solution was not. To the developers’ credit, they found a way to accomplish the goal. However, there were still a few rocks left out on the road on the journey to ILE. In the first place, the concept was sometimes difficult to grasp by the old green-screen crowd (like us). And second, IBM didn’t provide enough tools for managing the ILE model. One such missing tool became apparent to us in one of our recent endeavors.
All programs, ILE and OPM alike, run within an activation group. Activation groups are a wonderful way to encapsulate and insulate an application from the rest of the world. You can designate open data paths, file commitments, SQL cursors, and other important resources to a specific activation group. Those resources are then isolated and only available to programs within that activation group.
If you simply convert your OPM RPG programs into RPG IV programs and do nothing else, the new programs run in the default activation group, just as the OPM programs do. However, to really take advantage of all that RPG IV has to offer (subprocedures, local variables, and more), you need to run your programs in an activation group other than the default. As is customary with this platform, there is more than one way to accomplish this task.
The Why
If you specify *NO to the DFTACTGRP parameter, you must specify the ACTGRP parameter. The default for this parameter is to run in a named activation group called QILE. Running your RPG IV program in QILE is better than running it in the default activation group; however, if everybody took this default, then you would lose the advantage of isolation of applications. If your programs run in QILE and other programs that you use also happen to run in QILE, those programs would not be isolated within the activation group. Therefore, you should pick a different, unique name for the activation group where you will run your programs.
Another option on the ACTGRP parameter is *NEW, which indicates that you want the system to create a new activation group every time this program is called. Since there is some overhead involved (read: response-time degradation) when creating activation groups, this option should be used sparingly. Still another option for the ACTGRP parameter is *CALLER. This option specifies that you want this program to run in the same activation group as the program that called it.
The idea for this option is to put menu driver programs in a named activation group and then specify *CALLER for any subsequent programs called. All of the programs end up running in the same activation group, but maintenance would be easier if you needed to change the name of an activation group.
As you can see, there are quite a few different schemes you can employ to use activation groups. Your programs will run within the correct activation group if you remember to use the correct compile option or use the ACTGRP keyword in the header specifications of your RPG IV programs. It would be really nice if IBM would give us the ability to specify the activation group within the source for CL, wouldn’t it?
We elected to put all of our programs in a uniquely named activation group. We soon discovered that not all of our programmers were satisfied with the results of our election. They wanted a recount! Eventually, we found that some programs were being compiled into the default activation group, which caused problems with the scope of certain override commands. Although we had created PDM commands to compile both RPG and CL programs, programmers would occasionally forget to use them. What we needed was a way to easily see whether or not all of our ILE programs were in the correct activation group. So we wrote a utility to do exactly that. Our utility, which we call List Activation Groups, consists of the RPG IV program PGMACTG and the List Activation Groups (LSTACTGRP) command. You can download the source code for these two objects at www.midrangecomputing.com/mc
.
The concept behind our program is simple: List all of the programs in a library to a user space. Process that list, identifying programs included or excluded (depending upon the selection parameters) from the specified activation group. Print the names of the programs that meet the specified criteria.
Figure 1 contains an abbreviated version of the RPG program PGMACTG. Notice that it contains two subprocedures, CrtUsrSpc and GetActGrp, which run APIs that perform specific functions. The CrtUsrSpc subprocedure runs the QUSCRTUS API, which creates a user space to retain our output, and the QUSPTRUS API, which retrieves the address in memory of the newly created user space.
The second subprocedure, GetActGrp, runs the QCLRPGMI API, which gets information about a specific program. (We have listed the parameters for this API in Figure
2. It would behoove you to take a minute to study the parameters so you can fully understand how this API works.) This subprocedure returns a pointer to a data structure (PGMRECEIVE) that contains the information about the requested program. But if you look closely at the data structure, you will see that there are no subfields defined for the structure in the subprocedure. That’s because the subprocedure does not use any of the fields returned from the API. The subprocedure simply gives the caller a pointer to the data
The How
structure. If you look back in the mainline code, you will see a data structure called PgmData that is based upon a pointer called pPgmData. This pointer is the same one that was returned from the subprocedure; it and reflects the address of the data structure contained in the subprocedure that has the information about the program.
Now that we have identified the function of the two subprocedures, let’s talk about the main logic of the program. The definition parameters are passed to our program via the LISTACTGRP command. The program first creates the user space. Remember that the pointer is established at this time too, so the user space is ready to use. Next, we run the QUSLOBJ API to put the programs for the specified library into the newly created user space. The result in the field named QusNbrLE00 tells the program how many programs were placed in our list.
We then print the heading of the report (see Figure 3) and walk through the user space processing the list of programs. Each program in the list is contained in a data structure (QusH0300), which is based on a pointer. We extract each item in the list by incrementing the pointer (p100) by the size of each entry in the list (QusSEE00). Each program is submitted to our GetActGrp subprocedure, where the memory pointer is established for information about the program in question. If the program meets the list selection criteria, it is printed on the list. The process repeats itself until the list of programs in the user space has been completely processed.
When it comes to learning all about RPG IV and ILE, understanding activation groups is one of the biggest hurdles. But you should take the time to learn. Failure to do so could result in your missing the boat to the future. There is no weapon as powerful as knowledge, and that is certainly the case in our profession. Consider the time you spend learning about ILE and activation groups as an investment in your future.
The When
fQsysprt o f 132 printer oflind(*inof)
d ActionCode S 1
d InLib S 10
d ListFormat S 8
d No C '0'
d ObjNamLIb S 20 inz('*ALL *LIBL ')
d ObjType S 10
d PrintIt S 1
d TotOut S 7 0
d UserSpace S 20 inz('PGMACTGRP QTEMP')
d x S 1 0
d PgmData DS 502 based(pPgmData)
d PgmOwner 29 38
d PgmText 111 160
d EarliestRel 268 273
d ActGroup 473 502
d InActGrp DS 152
d NbrInList 1 2B 0
d AActGrp 30 dim(5)
d QusH0300 DS Based(pGeneralDs)
d QusIS00 104 104
d QusOlD00 125 128B 0
d QusNbrLE00 133 136B 0
d QusSEE00 137 140B 0
d QusL010003 DS based(p100)
d QusObjNU 1 10
d QusOLNU 11 20
d QusEC DS 116
d QusBPrv 1 4B 0 inz(116)
d QusBAvl 5 8B 0
c *entry Plist
c Parm InLib
c Parm InActGrp
c Parm ActionCode
c move InLib ObjNamLib * Create user space for object list information
c Eval pGeneralDs = CrtUsrSpc(UserSpace) * List programs to user space
c Call 'QUSLOBJ'
c Parm UserSpace
c Parm 'OBJL0100' ListFormat
c Parm ObjNamLib
c Parm '*PGM' ObjType
c Parm QusEc * If the list API was complete or partially complete
c if QuSIS00 = 'C' OR QuSIS00 = 'P' * Load the list data structure
c Eval p100 = pGeneralDs + QusOLD00 * Print heading
c except Headng * Process list of programs in user space
c Do QusNbrLE00 * Get activation group that program is compiled to run in
c eval pPgmData = GetActGrp(QusOlNu:QusObjNu) * Determine whether or not to print
c clear PrintIt
c do NbrInList x
c if ActionCode = 'E'
c if AActGrp(x) = ActGroup
c eval PrintIt = NO
c endif
c endif
c if ActionCode = 'I'
c if AActGrp(x) = ActGroup
c leave
c endif
c if x = NbrInList
c eval PrintIt = No
c endif
c endif
c enddo
c if PrintIt No
c except Detail
c eval TotOut = TotOut + 1
c endif
c Eval p100 = p100 + QusSEE00
c EndDo
c Endif
c except Total
c eval *inlr = *on
oQsysprt e Headng 2 02
**** remainder of output specs omitted
P CrtUsrSpc B export
d CrtUsrSpc PI *
d PasSpcName 20
d ListPtr S *
d SpaceAttr S 10 inz
d SpaceAuth S 10 INZ('*CHANGE')
d SpaceLen S 9B 0 INZ(2048)
d SpaceReplc S 10 INZ('*YES')
d SpaceText S 50
d SpaceValue S 1
* Create the user space
c call 'QUSCRTUS'
c parm PasSpcName
c parm SpaceAttr
c parm SpaceLen
c parm SpaceValue
c parm SpaceAuth
c parm SpaceText
c parm '*YES' SpaceReplc
c parm QusEc * Get pointer to user space
c call 'QUSPTRUS'
c parm PasSpcName
c parm ListPtr
c return ListPtr
P CrtUsrSpc E
P GetActGrp B export
d GetActGrp PI *
d InLib 10 const
d InPgm 10 const
d PgmReceive DS 502
d FormatName s 8
d PgmAndLib s 20
d ReceiveLen S 10i 0
c Eval PgmAndLib = InPgm + InLib
c Call 'QCLRPGMI'
c Parm PgmReceive
c Parm 502 ReceiveLen
c Parm 'PGMI0200' FormatName
c Parm PgmAndLib
c Parm QusEc
c return %addr(PgmReceive)
P GetActGrp E
Figure 1: The PGMACTG program is used to identify ILE programs that are, or are not, part of specified activation groups.
Description Type Attribute Size
Receiver Variable Output Char Varies
Length of Receiver Variable Input Binary 4
Record Format Name (This describes Input Char 8 the format of the data that will be
returned.) Possible values:
* PGMI0100: Basic information * PGMI0200: Basic information plus
SQL statement information for OPM programs * PGMI0300: Program size information
Qualified Program Name. (Bytes 1 to 10 Input Char 20 are object name; 11 to 20 are library
name.)
Standard Error Data Structure I/O Char Varies
Figure 2: Use the QCLRPGMI API to retrieve information about a program.
DATE: 3/16/01 List activation programs PAGE: 1
PROGRAM LIB RELEASE ACTIVATION GROUP OWNER TEXT
ATN002CL OL8 V4R5M0 BOSS Attn key handler
CENTER1 OL8 V2R3M0 BOSS Center text
CD0021R1 OL8 V4R5M0 *DFTACTGRP BOSS Calc discount
CD0022R1 OL8 V4R5M0 *NEW BOSS Calc freight
COMPFAIL OL8 V4R5M0 PGMR compile failures
CPYFTEST OL8 V4R5M0 PGMR
DK1019C OL8 V4R5M0 *NEW BOSS Get printer overrides
DK1025C OL8 V4R5M0 *DFTACTGRP BOSS Init LDA
DK1033C OL8 V4R4M0 QILE OP2 Submit batch job
DK1033R1 OL8 V4R4M0 QILE OP2 Submit batch job
EXT001C OL8 V4R5M0 PGMR Extract batch numbers
EXT001R OL8 V4R5M0 *DFTACTGRP PGMR Extract batch numbers
TOTAL PROGRAMS.......... 12
Figure 3: LSTACTGRP makes it easy to spot-check activation group assignments.
LATEST COMMENTS
MC Press Online