Using the services

There are 26 callable services available for task synchronization:

To use Pause, Release, and Transfer, a program must first allocate a PE by calling the Allocate_Pause_Element service. In response, the system allocates a PE and returns a pause element token (PET) that identifies the pause element (PE).

You use the PET returned from Allocate_Pause_Element to identify the allocated PE until either:

When you are finished with the PE, call the Deallocate_Pause_Element service to return the PE to the system. If a task is asynchronously ABENDed while it is paused, the system itself invalidates the PE, and it cannot be reused for pause requests. Thus, return an invalidated PE to the system as soon as possible by a call to Deallocate_Pause_Element.

Though the PE remains allocated until you deallocate it, you can use a PET for only one pair of calls, which result in a pause and a release of a task. When you specify a PET on a successful call to the Pause service or to pause a task through a successful call to the Transfer service, the system invalidates the input PET and returns an updated PET to identify the PE. Use the updated PET to reuse the PE or to deallocate the PE.

Figure 1 shows, in pseudocode, the sequence of calls to allocate a PE, pause the current task, release the task, and deallocate the PE.
Figure 1. Pause and Release Example
/* Common variables              */  |
                                     |
 Dcl PET char(16);                   |
                                     |
    Workunit #1                      |     Workunit #2
                                     |
 /* Workunit #1 variables        */  | /* Workunit #2 variables       */
 Dcl Auth1 char(4);                  | Dcl Auth2 char(4);
 Dcl RC1 fixed(32);                  | Dcl RC2 fixed(32;
 Dcl Updated_pet char(16);           | Dcl RelCode binary(24);
 Dcl RetRelCode binary(24);          |
                                     |
 Auth1 = IEA_UNAUTHORIZED;           | Auth2 = IEA_UNAUTHORIZED;
            .                        |            .
            .                        |            .
            .                        |            .
 /* Allocate a Pause Element      */ |
 Call IEAVAPE (RC1,Auth1,PET);       |
                                     |
 /* Pause Workunit #1             */ |
 Call IEAVPSE (RC1,Auth1,PET,        |
            Updated_PET,RetRelCode); |
                                     |
/*processing pauses until released*/ | RelCode = '123';
                                     | /* Release Workunit #1         */
                                     | Call IEAVRLS (RC2,Auth2,PET,
            .                        |               RelCode);
            .                        |
            .                        |
 PET = UPET;                         |
 Call IEAVPSE (RC1,Auth1,PET);       |
            Updated_PET,RetRelCode); |
                                     |
/*processing pauses until released*/ | RelCode = '345';
            .                        | /* Release Workunit #1        */
            .                        | Call IEAVRLS (RC2,Auth2,PET,
            .                        |               RelCode);
 /* Deallocate the pause element  */ |
 Call IEAVDPE (RC1,Auth1,            |
            Updated_PET)             |                                

The Pause, Release, and Transfer services also provide a release code field that programs can use to communicate, to indicate, for example, the reason for a release. The program that calls the Release service can set a release code.

The release code is particularly useful when a task might be released before it is paused (prereleased). When a subsequent call to the Pause service occurs, the system does not pause the task; instead, it returns control immediately to the calling program and provides the release code specified on the release call.

Figure 2 shows, in pseudocode, the sequence of calls needed to allocate a PE, prerelease a task, and deallocate the PE
Figure 2. Release and Pause Example
/* Common variables              */  |
                                     |
 Dcl PET char(16);                   |
                                     |
    Workunit #1                      |     Workunit #2
                                     |
 /* Workunit #1 variables        */  | /* Workunit #2 variables       */
 Dcl Auth1 fixed(32);                | Dcl Auth2 fixed(32);
 Dcl RC1  fixed(32);                 | Dcl RC2   fixed(32);
 Dcl Updated_PET char(16);           | Dcl RelCode binary(24);
 Dcl RetRelCode binary(24);          |
                                     |
 Auth1 = IEA_UNAUTHORIZED;           |
                                     |
 /* Allocate a Pause Element      */ |
 Call IEAVAPE (RC1,Auth1,PET);       |
            .                        | Auth2 = IEA_UNAUTHORIZED;
            .                        | RelCode ='123';
            .                        |
                                     | /* Release Workunit #1         */
                                     | Call IEAVRLS (RC2,Auth2,PET,
                                     |               RelCode);
 /* Pause Workunit #1             */ |            .
 Call IEAVPSE (RC1,Auth1,PET,        |            .
            Updated_PET,RetRelCode); |            .
                                     |
/*check release code and continue */ |
            .                        |
            .                        |
            .                        |
 /* Deallocate the pause element  */ |
 Call IEAVDPE (RC1,Auth1,            |
            Updated_PET);            |

If you make a release request (through Release or Transfer) specifying a PET that identifies a PE that has not yet been used to pause a task, the system marks the PE as a prereleased PE. If a program tries to pause a task using a prereleased PE, the system returns control immediately to the caller; it does not pause the task. Instead, it resets the PE. As soon as a PE is reset, it can be reused for another Pause and Release, but, as stated earlier, you use the returned updated PET for the next reused PE.

The Pause and Release services are very similar to the WAIT and POST macros, but the Transfer service provides new function. You can use Transfer to either:

Figure 3 shows an example of using the Transfer service to release a task without pausing the current task.

Because the Transfer service can affect multiple units of work, using Transfer requires you to work with three PETs:

  1. The current pause element token (CurrentDuPet in Figure 3) identifies the allocated pause element that Transfer is to use to pause the current task (the caller of the Transfer service). When you do not need to pause the current task, you set this token to binary zeros, as shown in Figure 3.
  2. The updated pause element token (UPET2 in Figure 3), which the system returns when you specify a current pause element token. You need this updated token to reuse the pause element on a subsequent Pause or Transfer or to deallocate the pause element. If you set the current token to binary zeros, as done in Figure 3, the contents of the updated pause element token are not meaningful.
  3. The target token (TargetDuPET in Figure 3) identifies the allocated pause element that Transfer is to use to release a task. In Figure 3, it contains the PET that identifies the PE used to pause Workunit #1.
A current release code and a target release code are also available on the call to Transfer. Whether or not each code contains valid data depends on conventions set by the different parts of your program
Figure 3. Transfer without Pause Example
/* Common variables              */  |
                                     |
 Dcl PET char(16);                   |
                                     |
         Workunit #1                 |  Workunit #2
                                     |
/* Workunit #1 variables         */  | /* Workunit #2 variables        */
 Dcl Auth1  char(4);                 | Dcl Auth2  char(4);
 Dcl RC1    char(4);                 | Dcl RC2   char(4);
 Dcl UPET1 char(16);                 | Dcl CurrentDuRelCode binary(24);
 Dcl RetRelCode binary(24);          | Dcl CurrentDuPET char(16);
           .                         | Dcl UPET2 char(16);
           .                         | Dcl TargetDuPET  char(16);
           .                         | Dcl TargetDuRelCode char(3);
Auth1 = IEA_UNAUTHORIZED;            |
/* Allocate a Pause Element      */  | Auth2 = IEA_UNAUTHORIZED;
 Call IEAVAPE (RC1,Auth1,PET);       |           .
                                     |           .
/* Pause Workunit #1             */  |           .
 Call IEAVPSE (RC1,Auth1,PET,UPET1,  | TargetDuRelCode = '123';
              RetRelCode);           | /* no pause-set token to zeros  */
                                     | CurrentDuPet =''B;
                                     | TargetDuPET =  PET
/*processing pauses until transfer*/ |
                                     | /* Transfer to Workunit #1      */
                                     |  Call IEAVXFR (RC2,Auth2,
                                     |               CurrentDuPET,UPET2,
                                     |               CurrentDuRelCode,
                                     |               TargetDuPET,
                                     |               TargetDuRelCode);
/*processing continues           */  |           .
                                     |           .
 /* Deallocate the Pause Element */  |           .
 Call IEAVDPE (RC1,Auth1,UPET1);     |