Showing posts with label STOP RUN. Show all posts
Showing posts with label STOP RUN. Show all posts

Sunday, 22 September 2013

COBOL Program Termination and Reentry: State and Run Units

A subprogram that executes GOBACK can be called again with its changed Working-Storage still present. Returning control and resetting program state are separate events, which is the central rule behind COBOL program termination and reentry.

COBOL program termination and reentry showing main program subprogram and next-call state
Termination selects the return path; INITIAL, CANCEL, and storage sections determine state on the next call.

Main program, subprogram, and run unit

The first COBOL program in a run unit is the main program. Programs it calls are subprograms; no source declaration permanently marks a separately compiled program as one or the other. The same program can therefore behave differently depending on how it is entered. See COBOL application structure for the calling hierarchy.

Two questions: when a program ends, determine where control must go. When it is called again, determine whether Working-Storage should retain its last-used values or return to its initial values.

Termination statements compared

StatementIn a main programIn a subprogramScope
GOBACKReturns to the caller of the main program, often the operating system.Returns to the statement after the active CALL.Adapts to the program's role.
EXIT PROGRAMNo action.Returns to the calling program without ending the run unit.Called-program return only.
STOP RUNTerminates the run unit and returns to the caller of the main program.Terminates the run unit rather than returning one CALL level.Whole run unit or Language Environment enclave.

GOBACK works in both roles

PROCEDURE DIVISION USING LK-REQUEST LK-RESULT. PERFORM CALCULATE-RESULT GOBACK.

In a called program, GOBACK returns to the instruction after the active CALL. In a main program, it behaves like program termination and returns to the main program's caller. Statements placed after an executed GOBACK are not run, so keep it last in the path.

The dedicated COBOL EXIT and GOBACK guide owns detailed statement syntax. This page concentrates on return scope and reentry state.

EXIT PROGRAM returns from a subprogram

IF LK-REQUEST-VALID = 'N' MOVE 12 TO RETURN-CODE EXIT PROGRAM END-IF

EXIT PROGRAM returns from a called program without ending the run unit. In a main program it has no effect. When a called program reaches its end with no next executable statement, Enterprise COBOL supplies an implicit EXIT PROGRAM, but an explicit termination path is easier to review.

STOP RUN ends the run unit

MOVE 8 TO RETURN-CODE STOP RUN.

STOP RUN closes files in programs belonging to the run unit, terminates the run unit, and returns using the current RETURN-CODE value according to IBM's documented rules. If a subprogram executes STOP RUN, control does not simply return to its immediate caller.

CICS boundary: IBM states that STOP RUN in a CICS environment terminates the entire transaction and its programs. Use the application framework's normal return design; the CICS transaction-flow guide explains task completion.

For statement-specific details, use the separate COBOL STOP RUN page.

Why a returned subprogram can keep old values

IDENTIFICATION DIVISION. PROGRAM-ID. COUNTER1. WORKING-STORAGE SECTION. 01 WS-CALL-COUNT PIC 9(4) VALUE ZERO. LINKAGE SECTION. 01 LK-CALL-COUNT PIC 9(4). PROCEDURE DIVISION USING LK-CALL-COUNT. ADD 1 TO WS-CALL-COUNT MOVE WS-CALL-COUNT TO LK-CALL-COUNT GOBACK.

A normally returned subprogram is usually left in its last-used state. Two calls to COUNTER1 in the same run unit can therefore return 1 and then 2. Return points for performed ranges are reset, but ordinary Working-Storage values can persist.

This is different from Working-Storage versus Local-Storage: Local-Storage is allocated for each invocation and its VALUE clauses are applied on entry.

Three ways to obtain initial state

Use IS INITIAL on PROGRAM-ID

PROGRAM-ID. COUNTER1 IS INITIAL.

The program and its contained programs enter initial state whenever called. Items with VALUE clauses are restored, altered GO TO and PERFORM state is reset, and non-EXTERNAL files are closed as part of initial-state handling.

Compile with the INITIAL option

The compiler option makes the program and its nested programs behave as if IS INITIAL were coded. The focused COBOL INITIAL compiler-option guide covers scope and defaults.

CANCEL an inactive dynamically called program

CALL WS-PROGRAM-NAME USING WS-REQUEST WS-RESULT CANCEL WS-PROGRAM-NAME CALL WS-PROGRAM-NAME USING WS-REQUEST WS-RESULT

A valid CANCEL breaks the program's logical connection so the next call enters initial state. IBM notes that no action is taken when the target has not been dynamically called in the run unit. Do not cancel an active program, a caller above the current program, or a target still active on another thread.

Caller and subprogram example

01 WS-PGM-NAME PIC X(8) VALUE 'COUNTER1'. 01 WS-COUNT PIC 9(4). CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'FIRST=' WS-COUNT CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'SECOND=' WS-COUNT CANCEL WS-PGM-NAME CALL WS-PGM-NAME USING WS-COUNT DISPLAY 'AFTER CANCEL=' WS-COUNT

With the preceding counter subprogram and a dynamic call, typical values are 1, 2, and then 1 after CANCEL. The COBOL CALL statement guide covers USING modes and exception phrases.

Common termination and reentry mistakes

  • Using EXIT PROGRAM in the main program: it performs no termination action there.
  • Using STOP RUN as a subprogram return: it ends the run unit rather than one call level.
  • Assuming Working-Storage resets on every CALL: a returned subprogram is normally in last-used state.
  • Confusing INITIALIZE with IS INITIAL: INITIALIZE changes selected data items; IS INITIAL controls program state on entry.
  • Canceling after every call for performance: dynamic load and initialization work can add overhead; use CANCEL when lifecycle requirements call for it.
  • Ignoring open resources: design file, Db2, and CICS cleanup around the actual termination scope.

Official IBM references

Frequently asked questions

What is the safest COBOL termination statement for both main programs and subprograms?

GOBACK is commonly used because it returns appropriately from either a main program or a called subprogram. The required behavior and site standards still determine the final choice.

Does EXIT PROGRAM end a main COBOL program?

No. EXIT PROGRAM has no effect when executed in a main program. It returns control from a called subprogram without ending the run unit.

Does Working-Storage reset when a COBOL subprogram is called again?

Usually not. A normally returned subprogram is generally reentered in its last-used state. IS INITIAL, the INITIAL compiler option, or a valid CANCEL can cause initial-state entry; LOCAL-STORAGE is allocated afresh for each invocation.

What does STOP RUN do in a COBOL subprogram?

STOP RUN ends the run unit rather than returning only one level to the immediate caller. In CICS it terminates the transaction, so it is not a substitute for a normal subprogram return.

Review rule: choose the return scope first, then document whether a later CALL must see last-used Working-Storage or initial state.

New In-feed ads