Making applications threadsafe

When you make an application program threadsafe, you can use the open transaction environment, avoid TCB switching, and gain performance benefits.

Before you begin

To use threadsafe application programs, ensure that the system initialization parameter FORCEQR is not set to YES. FORCEQR forces programs defined as threadsafe to run on the QR TCB, and it might be set to YES as a temporary measure while problems connected with threadsafe-defined programs are investigated and resolved.

Also, select an appropriate setting for the system initialization parameter FCQRONLY in your file-owning CICS® regions. If FCQRONLY is set to YES, CICS forces all file control requests in the CICS region to run on the QR TCB.
  • If you use IPIC connections to function ship file control requests to remote CICS TS 4.2 or later regions, to improve performance for those connections set FCQRONLY to NO in the file-owning regions.
  • If you use only MRO links or ISC over SNA connections, or your file-owning regions are earlier than CICS TS 4.2 , set FCQRONLY to YES in the file-owning regions.

If you are using CICS intercommunication to make requests for functions or programs to run in remote CICS systems, choose IP interconnectivity (IPIC) over TCP/IP connections between the CICS systems to provide optimal support for threadsafe applications. With IPIC connections, CICS uses an open TCB to run the mirror program that manages the request on the remote CICS system, providing improved throughput. With other connection types, CICS does not use an open TCB to run the mirror program. The EXEC CICS LINK command, used for distributed program link (DPL), is threadsafe for IPIC connections to remote CICS regions where a long-running mirror is used, but not for other connection types.

About this task

Threadsafe programs explains what it means for a program to be threadsafe, and the circumstances when TCB switching takes place between open TCBs and the QR TCB.

To make an application program threadsafe and enable it to remain on an open TCB, use the following procedure.

Procedure

  1. Define the program to CICS as threadsafe, by specifying CONCURRENCY(THREADSAFE) in the PROGRAM resource definition.

    For a program that is defined as OPENAPI, CICS requires the CONCURRENCY(THREADSAFE) option. Only code that has been defined as threadsafe is permitted to run on open TCBs. By defining a program to CICS as threadsafe, you are specifying only that the application logic is threadsafe, not that all the EXEC CICS commands included in the program are threadsafe. CICS can ensure that EXEC CICS commands are processed safely by using TCB switching, but, to permit your program to run on an open TCB, CICS needs you to guarantee that your application logic is threadsafe.

    Alternatively, you can define the program as CONCURRENCY(REQUIRED) to enable your program to run from the start on an open TCB. Programs defined as CONCURRENCY(REQUIRED) must be coded to threadsafe standards as they must always run on an open TCB. The type of open TCB used depends on the API setting.

  2. Ensure that the program logic, that is, the native language code between the EXEC CICS commands, is threadsafe.

    If you define a program to CICS as threadsafe but include application logic that is not threadsafe, the results are unpredictable, and CICS cannot protect your program from the possible consequences. To make your program logic threadsafe, you must use appropriate serialization techniques when accessing shared resources, to prohibit concurrent access to those resources. When you use EXEC CICS commands to access resources such as files, transient data queues, temporary storage queues, and Db2® tables, CICS ensures threadsafe processing, but for any resources that are accessed directly by user programs, such as shared storage, the user program must ensure threadsafe processing.

    Typical examples of shared storage are the CICS CWA, the global work areas for global user exits, and storage acquired explicitly by the application program with the shared option. Check whether your application programs use these types of shared storage by looking for occurrences of the following EXEC CICS commands:
    • ADDRESS CWA
    • EXTRACT EXIT
    • GETMAIN SHARED
    The load module scanner utility includes a sample table, DFHEIDTH, to help you identify CICS commands that give access to shared storage. Although some of these commands are themselves threadsafe, they all give access to global storage areas, so the application logic that follows these commands and uses the global storage areas can potentially not be threadsafe. To ensure that it is threadsafe, an application program must include the necessary synchronization logic to guard against concurrent update.
    Tip: When identifying programs that use shared resources, also include any program that modifies itself. Such a program is effectively sharing storage and you must consider it at risk.
    You can use the following techniques to provide threadsafe processing when accessing a shared resource:
    • Retry access, if the resource has been changed concurrently by another program, using the compare and swap instruction.
    • Enqueue on the resource, to obtain exclusive control and ensure that no other program can access the resource, using one of the following techniques:
      • An EXEC CICS ENQ command, in an application program.
      • An XPI ENQUEUE function call to the CICS enqueue (NQ) domain, in a global user exit program.
      • An MVS™ service such as ENQ, in an open API task-related user exit only when L8 TCBs are enabled for use. Note that the use of MVS services in an application that can run under the QR TCB might result in performance degradation because of the TCB being placed in a wait.
    • Perform accesses to shared resources only in a program that is defined as quasi-reentrant, by linking to the quasi-reentrant program using the EXEC CICS LINK command. This technique applies to threadsafe application programs and open API task-related user exits only. A linked-to program defined as quasi-reentrant runs under the QR TCB and can take advantage of the serialization provided by CICS quasi-reentrancy. Note that, even in quasi-reentrant mode, serialization is provided only for as long as the program retains control and does not wait.
    • Place all transactions that access the shared resource into a restricted transaction class ( TRANCLASS ), one that is defined with the number of active tasks specified as MAXACTIVE(1) . This approach effectively provides a very coarse locking mechanism, but might have a severe impact on performance.
    Note: Although the term threadsafe is defined in the context of individual programs, a user application as a whole can be considered threadsafe only if all the application programs that access shared resources obey the rules. A program that is written correctly to threadsafe standards cannot safely update shared resources if another program that accesses the same resources does not obey the threadsafe rules.
  3. For best performance, ensure that the program uses only threadsafe EXEC CICS commands.

    If you include an EXEC CICS command that is not threadsafe in a program that is defined as threadsafe and running on an open TCB, CICS switches back from the open TCB to the QR TCB to ensure that the command is processed safely. The results of your application are not affected, but its performance might be affected.

    The commands that are threadsafe are indicated in the command descriptions of the CICS API and SPI command topics with the statement This command is threadsafe . They are also listed in Threadsafe commands and Threadsafe SPI commands.

    The load module scanner utility includes a sample table, DFHEIDNT, to help identify any CICS commands in your applications that are not threadsafe.

  4. If any user exit programs are in the execution path used by the program, for best performance ensure that they are also coded to threadsafe standards and defined to CICS as threadsafe. These exits might be dynamic plan exits, global user exits, or task-related user exits. Also check that user exit programs supplied by any vendor software are coded to threadsafe standards and defined to CICS as threadsafe.

    A threadsafe user exit program can be used on the same open TCB as a threadsafe application that calls it, and it can use non-CICS APIs without having to create and manage subtask TCBs, and exploit the open transaction environment for itself. If any user exit programs in the execution path used by the program are not threadsafe, CICS switches to the QR TCB to run them, which might be detrimental to the application's performance.

    Be aware of the following important user exits:
    • The global user exits XEIIN and XEIOUT are called before and after EXEC CICS commands.
    • The global user exit XPCFTCH is called before a program defined to CICS receives control.
    • For CICS Db2 requests, the CICS Db2 task-related user exit DFHD2EX1 is threadsafe. Other important exits for CICS Db2 requests include the default dynamic plan exit DSNCUEXT, which is not defined as threadsafe, the alternative dynamic plan exit DFHD2PXT, which is defined as threadsafe, and the global user exits XRMIIN and XRMIOUT.
    • If you function ship CICS file control, transient data, or temporary storage requests to a remote CICS region over an IPIC connection, the requests are threadsafe and can run in the remote CICS region on an open TCB. Any global user exit programs that are called in the remote CICS region for file control, transient data, or temporary storage requests must be enabled as threadsafe programs for the best performance.
    1. To define a user exit program to CICS as threadsafe, you can specify appropriate attributes in its PROGRAM resource definition.
      • For a task-related user exit program, specify OPENAPI and THREADSAFE, or just THREADSAFE.
      • For a global user exit program, you cannot use OPENAPI, but you can specify THREADSAFE.

      If you specify CONCURRENCY(REQUIRED) on a global user exit program or task-related user exit program, CICS treats the program as if you had specified CONCURRENCY(THREADSAFE).

    2. Alternatively, to define a user exit program to CICS as threadsafe, you can specify appropriate options when you enable the program by using the EXEC CICS ENABLE PROGRAM command.
      • For a task-related user exit program, specify OPENAPI or THREADSAFE.
      • For a global user exit program, you cannot use OPENAPI, but you can specify THREADSAFE.
      When you enable an exit program using the OPENAPI or THREADSAFE option, this action indicates to CICS that the program logic is threadsafe, so CICS overrides the CONCURRENCY setting on the program definition for the exit and treats the exit program as threadsafe.
    3. To define a first-phase PLT global user exit program as threadsafe, specify THREADSAFE on the EXEC CICS ENABLE PROGRAM command.
      To ensure that global user exit programs (such as those that run at the recovery exit points) are available as early as possible during CICS initialization, it is common practice to enable them from first-phase PLT programs. Because first-phase PLT programs run so early in CICS initialization, you cannot use installed PROGRAM resource definitions or the program autoinstall user program to define the exit programs. CICS automatically installs exit programs that are enabled from first-phase PLT programs with CONCURRENCY(QUASIRENT) . However, the setting on the EXEC CICS ENABLE PROGRAM command overrides the CONCURRENCY(QUASIRENT) setting on the system autoinstalled program definition.