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.
/* 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.
/* 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:
/* 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); |