Showing posts with label CALL identifier. Show all posts
Showing posts with label CALL identifier. Show all posts

Sunday, 11 August 2013

COBOL DYNAM Compiler Option: Static vs Dynamic CALL

A COBOL program can call another program by writing CALL "PAYCALC" or by putting the program name in a data item and using CALL WS-PROGRAM-NAME. The DYNAM compiler option mainly affects the first form: CALL with a literal program name.

COBOL DYNAM compiler option diagram showing CALL literal with NODYNAM link-edit and DYNAM runtime load paths
Choose by CALL behavior.

What is the COBOL DYNAM compiler option?

DYNAM tells Enterprise COBOL to load separately compiled, nonnested programs dynamically when they are called with CALL literal. IBM documents the default as NODYNAM. The abbreviation is DYN, and NODYN is the abbreviation for NODYNAM.

With NODYNAM, a literal call is normally resolved through the link-edit step. With DYNAM, the called program is loaded at run time, and a later CANCEL can delete it from the run unit.

DYNAM vs NODYNAM

Option CALL literal behavior Good fit
NODYNAM The called program name is resolved through the link step. High-volume calls, stable subprograms, and programs where call path length matters.
DYNAM The called program is loaded dynamically at run time. Shared subprograms that change independently, optional routines, and cases where CANCEL is used to free storage.

CALL literal example

This is the form affected by DYNAM. The subprogram name is written directly in the source code.

CBL DYNAM

PROCEDURE DIVISION.
    CALL "TAXCALC" USING WS-INVOICE
                         WS-TAX-AMOUNT
    END-CALL
    GOBACK.

Compiled with DYNAM, this literal call is treated as a dynamic load at run time. Compiled with NODYNAM, the call is normally resolved when the program is linked.

CALL identifier is already dynamic

IBM documents that CALL identifier always results in a runtime load of the target program and is not affected by the DYNAM option. This is easy to miss when reviewing old code.

01 WS-PROGRAM-NAME      PIC X(8) VALUE "TAXCALC".

PROCEDURE DIVISION.
    CALL WS-PROGRAM-NAME USING WS-INVOICE
                               WS-TAX-AMOUNT
    END-CALL.

If a program already uses a data-name in the CALL statement, changing NODYNAM to DYNAM does not make that specific call more dynamic. It was already resolved by name at run time.

ON EXCEPTION with DYNAM

ON EXCEPTION can matter when a called program is missing from the runtime search path. IBM notes that for CALL literal, the exception condition can occur only when DYNAM is in effect. With NODYNAM, a missing statically resolved subprogram is usually caught earlier in the build or link process.

CALL "TAXCALC" USING WS-INVOICE
                     WS-TAX-AMOUNT
    ON EXCEPTION
       MOVE 16 TO WS-RETURN-CODE
END-CALL.

Do not use ON EXCEPTION as a substitute for proper deployment checks. It is a runtime safety path, not a reason to leave load libraries unclear.

Why use DYNAM?

DYNAM can make maintenance easier for common subprograms. If several applications call the same utility routine, a site may update that routine without relinking every caller, subject to local load library, binder, and change-control rules.

It can also help storage control in long-running programs. If a called program is no longer needed, CANCEL can remove the dynamically loaded program from the run unit.

Why keep NODYNAM?

NODYNAM is often better for call-heavy code. IBM performance guidance notes that DYNAM adds a longer path because the call goes through a library routine. The exact cost depends on the program and how often the call runs.

If a job calls the same small validation routine once for every input record, test carefully before switching to DYNAM. A call inside a ten-million-record loop is very different from a setup call that runs once.

Restrictions and cases to check

IBM documents restrictions for DYNAM. Do not use it for COBOL programs processed by the CICS translator or the CICS compiler option. IBM also documents restrictions for programs with EXEC SQL statements in certain environments, including CICS and Db2 call attach facility cases.

DLL use is another area to check. IBM states that if COBOL programs call programs linked as dynamic link libraries, the caller should be compiled with NODYNAM and DLL, not DYNAM.

Compile option example

Many shops set this option in a compile procedure rather than in the source. A source-level example is still useful when reading compiler listings or test programs.

CBL NODYNAM

IDENTIFICATION DIVISION.
PROGRAM-ID. PAYMAIN.

Before changing the option, check the compiler listing. The listing is the clean evidence of whether DYNAM or NODYNAM was in effect for the program you are testing.

Load library checks

Dynamic calls depend on the runtime search path. In batch, review the STEPLIB, job library setup, and site runtime libraries. In online regions, review the region procedure and program management rules used by the support team.

A common production problem is simple: the caller was compiled with DYNAM, but the called module was not in the expected library at execution time. The source code looked correct, but the runtime environment could not find the program.

Testing checklist

  • List every CALL literal and CALL identifier in the program.
  • Check whether the called program is linked with the caller or loaded from a runtime library.
  • Confirm CICS, SQL, CAF, DLL, and site standards before changing the option.
  • Run a missing-subprogram test if the application depends on ON EXCEPTION.
  • Compare CPU time and elapsed time for call-heavy programs.
  • Check load library order in the job or region where the program runs.

Migration review points

When moving older COBOL programs to a newer compiler, do not copy the old DYNAM setting blindly. Review how each called module is packaged, whether the program uses CICS or SQL, whether DLL rules apply, and whether the call sits inside a hot record loop.

For a high-volume batch driver, test one compile option change at a time. Keep the old listing, new listing, binder output, job statistics, and load-library evidence together so the next support person can see why the option was changed.

Common mistakes

Expecting DYNAM to affect CALL identifier

CALL WS-PROGRAM-NAME is already dynamic. The DYNAM option is mainly about nonnested, separately compiled programs called through CALL literal.

Changing the option without checking CICS or SQL

A batch test may work, but that does not prove the option is valid for a CICS or SQL environment. Check the actual execution environment before compiling production code.

Ignoring call frequency

A dynamic call in setup code may be harmless. A dynamic call inside a record loop can be expensive. Count the calls before arguing about the option.

Related Mainframe Forum guides

For nearby topics, read COBOL CALL statement examples, COBOL static call, COBOL COPY vs CALL, COBOL RENT compiler option, COBOL THREAD compiler option, and COBOL performance tuning tips.

External references

IBM documents the DYNAM compiler option, DYNAM performance considerations, and the COBOL CALL statement.

FAQ

What is the default for the COBOL DYNAM option?

IBM documents the default as NODYNAM.

Does DYNAM affect CALL identifier?

No. IBM documents that CALL identifier always causes a runtime load of the target program and is not affected by DYNAM.

When should I use NODYNAM?

Use NODYNAM when literal calls should be resolved through the link step, when call overhead matters, or when CICS, SQL, DLL, or site rules require it.

Can CANCEL unload a dynamically called program?

Yes. With dynamic calls, CANCEL can delete the called program from the run unit when it is no longer needed.

COBOL CALL Performance: Static, Dynamic, and Nested Calls

A COBOL batch job can spend a surprising amount of time transferring control between programs. The cost is small for one call, but it matters when a transaction driver calls the same validation module millions of times. The right choice depends on whether the subprogram name is fixed, whether the module must be loaded separately, and how the application is maintained.

COBOL CALL performance diagram comparing nested static and dynamic calls
Pick the call style.

What does CALL do in COBOL?

The CALL statement transfers control from one COBOL program to another program in the same run unit. The calling program passes data with the USING phrase, and the called program receives that data in its PROCEDURE DIVISION USING list.

CALL "TAXCALC" USING WS-GROSS-PAY
                     WS-TAX-AMOUNT
END-CALL

That example uses a CALL literal because the program name is hard-coded. A CALL identifier uses a data item to hold the program name, which lets the job choose the target at run time.

Static, dynamic, and nested calls at a glance

Call style Typical coding Best fit Tradeoff
Nested call CALL "INNER-PGM" inside a containing program Small helper logic that belongs inside one program source Less flexible for separate reuse
Static call CALL "TAXCALC" with NODYNAM Fixed subprogram names and stable batch applications Relink needed when called modules change
Dynamic call CALL WS-PROG-NAME or CALL literal with DYNAM Selectable routines, shared utility modules, plugin-style processing Runtime load and library lookup must be managed

CALL literal and CALL identifier

A CALL literal is easier for a reviewer to trace because the target name appears in the source. With NODYNAM, a nonnested CALL literal is normally handled as a static call. With DYNAM, that same source can behave like a dynamic call.

CALL "RATEEDIT" USING WS-RATE-AREA

A CALL identifier is dynamic. The program name comes from a working-storage item, parameter, file, or table. This is useful when one driver program chooses between several routines, but it also makes production diagnosis harder because the target module is not obvious from the statement alone.

01  WS-CALL-NAME PIC X(08) VALUE "RATEEDIT".

CALL WS-CALL-NAME USING WS-RATE-AREA
   ON EXCEPTION
      DISPLAY "CALL FAILED: " WS-CALL-NAME
END-CALL

Nested program calls

A nested program is coded inside another COBOL program. IBM documents nested calls as a structured way to keep helper logic close to the containing program and to reduce accidental changes to unrelated data. Nested programs can be called with a literal or identifier, subject to the scope rules of contained programs.

IDENTIFICATION DIVISION.
PROGRAM-ID. PAYDRVR.

PROCEDURE DIVISION.
    CALL "EDIT-PAY" USING WS-PAY-DATA
    GOBACK.

IDENTIFICATION DIVISION.
PROGRAM-ID. EDIT-PAY.
PROCEDURE DIVISION USING LS-PAY-DATA.
    GOBACK.
END PROGRAM EDIT-PAY.
END PROGRAM PAYDRVR.

Use nested programs for local helper routines that are not meant to be called across many load modules. Avoid them when the routine is a shared service that many programs must update independently.

Static CALL performance

A static call is usually faster to enter because the called program is resolved through link-edit or binder processing rather than found and loaded at run time. It also gives build-time visibility: if the called object is missing, the build process is more likely to expose the problem before the batch job starts.

The cost is maintenance. Static calls can make the load module larger, and a changed subprogram may require relink work. In a shop with many shared routines, that can turn one utility change into a batch of packaging work.

Dynamic CALL performance

Dynamic calls give the application more freedom. A program can call a module by name at run time, and a changed called program can often be replaced without rebuilding every caller. That is why dynamic calls are common for utility routines and configurable processing.

The tradeoff is runtime control. The correct module must be available through the job's load library search path, such as STEPLIB or site-standard runtime libraries. If the module is missing or the name is wrong, the failure happens during execution instead of during link-edit.

DYNAM and NODYNAM

The DYNAM compiler option tells Enterprise COBOL to treat nonnested, separately compiled CALL literal statements as dynamic calls. NODYNAM is the usual static choice for a fixed CALL literal. A CALL identifier is dynamic regardless of that option.

CALL "PAYCALC"     *> literal: static with NODYNAM, dynamic with DYNAM
CALL WS-PROG-NAME  *> identifier: dynamic

Do not decide this option from one statement alone. Check the compile option list, binder control, runtime libraries, and whether the program contains features with site restrictions, such as CICS or embedded SQL rules at your installation.

Parameter passing affects support more than speed

Most production issues around CALL do not come from the transfer itself. They come from mismatched parameters. IBM documents three common passing methods: BY REFERENCE, BY CONTENT, and BY VALUE.

Method What the called program gets Support note
BY REFERENCE Access to the caller's storage Changes in the called program affect the caller's data item.
BY CONTENT A copy of the caller's content The called program cannot change the original caller item.
BY VALUE A value, often for non-COBOL linkage Useful for C/C++ style calls, but both sides must agree.

Production checklist for CALL-heavy programs

  • List the top repeated calls in the job before changing compiler options.
  • Use CALL literal when the target program name is fixed and easy tracing matters.
  • Use CALL identifier only when the target truly needs to vary at run time.
  • Check whether DYNAM or NODYNAM is used by the compile JCL.
  • Verify the called module is available in the expected load library.
  • Match every CALL USING item with the called program's linkage layout.
  • Add ON EXCEPTION handling when a missing dynamic target should produce a clean message.

Common mistakes

Changing DYNAM without checking all calls

A compiler-option change can alter how fixed-name calls are loaded. Review every frequent CALL literal, especially in batch drivers and shared utility modules.

Using CALL identifier for a fixed name

If the target never changes, a literal is usually clearer. An identifier hides the target and makes source searches less useful during a production incident.

Passing the wrong layout

The called program does not know your intent. If the caller sends a 50-byte area and the callee expects 80 bytes, the symptom may appear as bad data, a protection exception, or a later logic error.

Related Mainframe Forum guides

For surrounding topics, read COBOL DYNAM Compiler Option, COBOL Application Structure, COBOL CALL by Reference, Content, and Value, COBOL CALL Statement, Static Call in COBOL, and COBOL RENT Compiler Option.

External references

IBM documents these rules in the Enterprise COBOL CALL statement, transferring control to another program, calling nested COBOL programs, and passing data pages.

FAQ

Is a static CALL always faster than a dynamic CALL?

Static calls usually avoid runtime load and lookup work, so they are often faster for repeated fixed-name calls. Measure the full job before changing a production compile option.

Is CALL identifier static or dynamic?

CALL identifier is dynamic. The target program name is taken from the value of the identifier at run time.

When should I use a nested COBOL program?

Use a nested program when the helper logic belongs inside one containing program and does not need to be separately shared by many applications.

What should I check first when a dynamic CALL fails?

Check the program name value, load library search path, compile option, and whether the called module exists under the expected name.

New In-feed ads