397
vote
Author: 
Dave Salt

Introduction

An email was recently sent to an online community in which a question similar to the following was asked:

“We have an in-house REXX utility that’s executed by entering ‘TSO UTILNAME’ on an ISPF command line. The utility displays a panel, but the fields on the panel aren’t always the same as the values I entered previously. Why is that?”

This type of problem usually occurs when the application designer doesn’t fully understand how the ISPF variable pools work. This article examines the 3 types of variable pool (i.e. FUNCTION, SHARED and PROFILE), and explains how to avoid this and other problems that can occur when the pools aren’t fully understood.

The FUNCTION Pool

The FUNCTION pool is unique to an individual program or procedure. The pool is created when a program starts to execute, and deleted when a program ends.

When a program sets a variable, it is stored in the program’s FUNCTION pool, and the value is unknown to other programs. If a program is running under ISPF and needs to make variables accessible to other programs, one way it can do this is to VPUT the variables in the SHARED or PROFILE pools. Other programs can then VGET the variables, even if they’re not directly called by the program.

To demonstrate, figure 1 shows a REXX procedure called PGMB. If PGMA calls PGMB which calls PGMC, then after PGMB has executed both PGMA and PGMC could VGET the MYVAR1 and MYVAR2 variables. Even if all 3 programs stopped executing, the variables would still be available to other programs (e.g. PGMD) that might be called at a later time. How long the variables remain available for depends on which pool the variables are put in (i.e. the SHARED or PROFILE pool), as discussed later in this article.


Figure 1: A REXX procedure called PGMB

/* REXX ‘PGMB’ copies variables to the SHARED pool. */
myvar1 = “White cat”
myvar2 = “Brown dog”
address ispexec “VPUT (MYVAR1 MYVAR2) SHARED”

TIP: If a program sets a variable that conforms to ISPF naming conventions (e.g. the variable name is no more than 8 characters in length), the variable is automatically available to any panels the program might display. The reverse is also true; i.e. any variables set by a panel are automatically available to the program that displayed it. In other words, the SHARED and PROFILE pools do not need to be used to pass values back and forth between a panel and the program that displayed it.

The SHARED Pool

The SHARED pool is created when an application is launched using the NEWAPPL or NEWPOOL parameters. For example, SDSF (an application that’s used for monitoring job queues) is usually launched using ‘NEWAPPL(ISF).’ The NEWAPPL parameter tells ISPF a new application is being launched, and the Application ID (in this example ‘ISF’) identifies the ‘internal’ name of the application.

During the time an application remains active, the SHARED pool remains available. For example, a program could display a panel that prompts for a value. If the value is VPUT in the SHARED pool, the value remains available throughout the entire length of the application. If the same panel is redisplayed several minutes or even hours later, the previously entered value can be redisplayed on the panel. Only when an application ends is the SHARED pool deleted and the values that were stored in the pool are lost.

The PROFILE Pool

The FUNCTION and SHARED pools exist only in memory; i.e. they are temporary and eventually get deleted. In contrast, the PROFILE pool consists of physical members that exist in a permanent data set. Each user has a personal PROFILE data set that’s attached to the ISPPROF ddname when they logon, and used throughout the entire ISPF session.

When an application is launched using the NEWAPPL parameter, the Application ID determines the name of the PROFILE member that will be used. For example, if an application is launched using NEWAPPL(ABC), ISPF looks for a member called ABCPROF in the users personal PROFILE data set. If the member isn’t found (i.e. this is the first time the user has ever launched the ABC application), ISPF creates the ABCPROF member. Any values that are stored in the PROFILE are then saved in that member.

Because the PROFILE is a physical member of a data set, any values that are stored in the member are kept ‘forever.’ For example, if a user enters a value on a panel and the value is stored in the PROFILE, the user can return to the panel at any future date and the value will still be there.

TIP: When an ISPF panel is displayed, it automatically searches the FUNCTION, SHARED, and PROFILE pools (in that order) for any variables that are used by the panel. This means that unless a panel wishes to override the default search order, it doesn’t need to explicitly retrieve variables from any of the pools.

CAUTION: Each PROFILE member can store a maximum of 64K of data. For example, if a program creates 64 variables and the value of each variable is 1,000 bytes long, storing the variables in the PROFILE would fill up the entire PROFILE member! For this reason, careful thought must be given before any variables are stored in the PROFILE. In general, if a value doesn’t need to be available ‘forever,’ it should not be stored in the PROFILE!

Executing the Same Application Concurrently

Almost all applications can run in multiple logical sessions. For example, SDSF can run concurrently on both sides of split screen. As SDSF uses the ‘ISF’ Application ID, all instances of the SDSF application use the same physical PROFILE member; i.e. ISFPROF. In other words, if any instance of the SDSF application updates the PROFILE in any of the split screen sessions, all instances of the SDSF application have access to the update.

In contrast, each application has its own individual SHARED pool. If an application updates the SHARED pool on one side of split screen, the same application running in another split screen is totally unaware of the update. This difference is extremely important to understand when designing applications that can be executed concurrently in multiple logical sessions.

To give an example, suppose an in-house application is used for promoting changes from one library to another. Any values that are entered on the panels are stored in the PROFILE for future use. A user could launch the application and enter the library name to promote from as ‘LIB1.’ This takes the user to a second screen, where they’re prompted to enter a target name. Before entering the target, the user splits the screen, re-launches the same application, and enters the library to promote from as ‘LIB2.’ Swapping back to the original screen, the user enters the target library name and presses ENTER. If the program that handles the promotion uses the value in the PROFILE to determine which library to promote from, the last value to be stored in the PROFILE was ‘LIB2.’ In other words, the application would promote all changes from LIB2, even though the user had entered LIB1 in the current split screen session!

Answering the Original Question

Now that variable pools are better understood, it’s time to answer the original question; i.e. why is it that when ‘TSO UTILNAME’ is entered on a command line, the values on the panel aren’t always the same as the values that were previously entered?

The answer is that the utility is probably being executed under different Application IDs. For example, ISPF options 1 and 2 (view and edit) both run under the ‘ISR’ Application ID. If ‘TSO UTILNAME’ is entered while in either of those options, values are stored in and retrieved from the ISRPROF member. But if ‘TSO UTILNAME’ is entered on an SDSF command line (which runs under the ‘ISF’ Application ID), the ISFPROF member is used instead. The values stored in ISFPROF could be different to the values stored in ISRPROF, and this is just two applications. There are dozens of other applications (e.g. vendor products, etc.) where ‘TSO UTILNAME’ could be entered.

TIP: An easy way to determine which Application ID is in effect is to enter ‘SWAP LIST’ on any ISPF command line. A pop-up panel displays all active sessions in a list, and the currently active session is flagged with an asterisk. The Application ID for each session is shown under the ‘Applid’ heading.

Solving the Problem

Understanding the problem is one thing, but how to solve it? If an application can be launched from anywhere (e.g. by entering ‘TSO UTILNAME’ on any command line), the application designer must make sure all variables are stored in and retrieved from the same PROFILE. Otherwise, it can lead to the problems that were just described.

Choosing a PROFILE is a simple matter of deciding which Application ID to use. A small application that only stores a few variables could use an existing Application ID (e.g. ISR) to ‘borrow’ some of the space available in the ISRPROF member. But if an application stores a lot of variables or the variables have long values, it’s better for the application to use its own exclusive PROFILE member.

The example in figure 2 demonstrates how an application can ensure it always runs under the same Application ID (in this example using the ‘ABC’ Application ID), regardless of where the application is launched from. It does this by first checking which Application ID it’s running under, and if it’s not the ‘ABC’ application it re-invokes itself using NEWAPPL(ABC).

Figure 2: Checking which Application ID it’s running under, and if it’s not the ‘ABC’ application, it re-invokes itself using NEWAPPL(ABC)

/* This REXX re-invokes itself to run under the ‘ABC’ Application ID.      */
arg var1 var2                                /* Receive input args (if any)*/
parse source . . execname .                  /* Get the name of this EXEC. */
address ispexec                              /* Pass commands to ISPF.     */
"VGET (ZAPPLID) SHARED"                      /* Get the Application ID.    */
if zapplid = "ABC" then nop                  /* If ‘ABC’ then continue.    */
else do                                      /* Else re-invoke this exec.  */
   "SELECT CMD(%"execname var1 var2") NEWAPPL(ABC)"
   EXIT                                      /* Exit when control returns  */
End                                          /* from the second execution. */
/* This logic only executes after this exec has re-invoked itself.         */
say "ZAPPLID = "zapplid                      /* Prove the applid = ‘ABC’.  */
say "VAR1 = "var1                            /* Prove arguments passed.    */
say "VAR2 = "var2                            /* All VPUTs/VGETs would now  */
EXIT                                         /* use the ABCPROF member.    */

Summary

ISPF variable pools are managed by the operating system, and for the most part their ‘inner-workings’ are transparent to both users and developers. However, understanding how the pools work can help to avoid problems.

In answering the original question (i.e. why is it that values entered on panels don’t always remain?), two other potential problems were also uncovered. Firstly, because of their fixed size, careful thought should always be given before any values are stored in the PROFILE. To avoid reaching the 64K limit, the following question should always be asked; does this value really need to be available ‘forever’?

Secondly, applications that can execute concurrently in multiple logical sessions must be designed with extra care. If an application uses PROFILE variables, it has to be aware that the variables could have been updated by an application that’s executing in a different session.

Dave Salt is the lead developer for the ISPF productivity tool. He has more than 20 years of experience designing and developing ISPF applications.


Average: 5 (2 votes)

Comments

Re: ISPF Variable Pools

Brilliant:

Could that development technique be implemented in environment Delphi 2005?

Re: ISPF Variable Pools

Excellent article on an often poorly understood topic.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.
  • You can use context links in the text to create context-related links to pages or sites that provide additional information about a word or phrase.
  • Allowed HTML tags: <br> </p> <p> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <object> <embed> <script>
  • You can use <object>, <embed> and <script> tags from the following sites to add media to your posts:

  • Each email address will be obfuscated in a human readble fashion or (if JavaScript is enabled) replaced with a spamproof clickable link.
  • You may link to images on this site using a special syntax
  • You may quote other posts using [quote] tags.
  • Web page addresses and e-mail addresses turn into links automatically.
  • You may link to webpages through the weblinks registry

More information about formatting options

Syndicate content