Using the services

Start of changeThere are 26 callable services available for task synchronization:End of change

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 work unit 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 only once, to pause and release a work unit. When you specify a PET on a successful call to the Pause service or to pause a work unit 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 work unit, release the work unit, 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 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_AUTHORIZED;             | Auth2 = IEA_AUTHORIZED;
            .                        |            .
            .                        |            .
            .                        |            .
 /* 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);
            .                        |
            .                        |
 /* Deallocate the pause element  */ |
 Call IEAVDPE (RC1,Auth1,            |
             Updated_PET);           |

The Pause, Release, and Transfer services also provide a release code field that is particularly useful when a dispatchable unit might be released before it is paused. The program that calls the Release service can set a release code.

Release code is returned to the invoker of Pause and can be used to communicate the reason for the release.

Figure 2 shows, in pseudocode, the sequence of calls needed to allocate a PE, prerelease a work unit, 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_AUTHORIZED;             |
                                     |
 /* Allocate a Pause Element      */ |
 Call IEAVAPE (RC1,Auth1,PET);       |
            .                        | Auth2 = IEA_AUTHORIZED;
            .                        | 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 or SRB, the system marks the PE as a prereleased PE. If a program tries to pause a work unit using a prereleased PE, the system returns control immediately to the caller; it does not pause the work unit. 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 each subsequent reuse of the 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 dispatchable unit without pausing the current work unit.

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 dispatchable unit (the caller of the Transfer service). When you do not need to pause the current dispatchable unit, 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 dispatchable unit. 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  fixed(32);               | Dcl Auth2  fixed(32);
 Dcl RC1    fixed(32);               | Dcl RC2   fixed(32);
 Dcl UPET1 char(16);                 | Dcl CurrentDuRelCode char(3);
 Dcl RetRelCode binary(24);          | Dcl CurrentDuPET binary(24);
           .                         | Dcl UPET2 char(16);
           .                         | Dcl TargetDuPET  char(16);
           .                         | Dcl TargetDuRelCode binary(24);
Auth1 = IEA_AUTHORIZED;              |
/* Allocate a Pause Element      */  | Auth2 = IEA_AUTHORIZED;
 Call IEAVAPE (RC1,Auth1,PET);       |           .
                                     |           .
/* Pause Workunit #1             */  |           .
 Call IEAVPSE (RC1,Auth1,PET,UPET1,  | TargetDuRelCode = '123';
              RetRelCode);           | /* no pause-set token to zeros  */
                                     | CurrentDuPet ='';
                                     | 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);     |