Converting Programs to Threadsafe
When reviewing programs, it is important to remember that there is no automated method to tell if a program is threadsafe, or to convert a program. However, there are a few rules of thumb and an IBM tool that can help.
First, pre-LE COBOL programs can not be made threadsafe.
Second, programs must be re-entrant to be threadsafe. COBOL programs compiled with RENT are automatically re-entrant; re-entrancy for assembler programs can be easily verified by linking the program as RENT, and setting RENTPGM=PROTECT. If the program isn’t re-entrant it will abend ASRA.
Third, applications that have no transaction affinities are more likely to be threadsafe than applications with affinities.
IBM supplies a source module scanner to help identify potentially non-threadsafe programs. The scanner, DFHEISUP, works by scanning application load modules looking for occurrences of commands found in member DFHEIDTH. Details of this utility can be found in the CICS Operations and Utilities Guide. DFHEISUP will report, for example, that a program issues an ADDRESS CWA command; since the CWA is often used to maintain counters or address chains, a program addressing the CWA could be using it in a non-threadsafe manner. On the other hand, the program could also be using the CWA to check for operational flags, file DD names, or other uses that do not raise threadsafe issues.
While DFHEISUP is helpful in the process of identifying threadsafe applications, it is critical to have a solid understanding of the application in question. Each program that shows up in the DFHEISUP report must be reviewed; if the area flagged in the report is actually used by the program, determine if the use would make the program non-threadsafe. Also, review all calls, links and xctl’s from the program to see if addressability to the area is being passed to other programs; if it is, then those programs must also be reviewed.
You can tell a program is thread safe based on few rules, if a program follows that.
Converting Non-Threadsafe Code
Once the program review has been completed, and the non-threadsafe code has been identified, what remains is to decide what to do. There are three basic methods of dealing with non-threadsafe code:
The first alternative is to do nothing.
While it may seem counter-intuitive, sometime the best thing to do is to leave the code as it is. In some cases, the data may no longer be used, or the data may not need to be completely accurate. For example, one of the first applications I converted to threadsafe maintained statistics in a shared storage area. These statistics were implemented by the programmer who had added a new data-compression feature to the application, and were used to keep track of how well the compression was working. At the time of the threadsafe conversion, the data-compression had been in place for over a year, and no one was concerned with how well it worked. I updated the documentation to state that the compression statistics were no longer reliable, and left the code unchanged.
Another rational for doing nothing is if the non-threadsafe code is totally contained within a small percentage of the programs in an application. In this case, the non-threadsafe programs can remain as QUASIRENT while the rest of the application is changed to THREADSAFE. CICS will automatically handle switching transactions back to the QR TCB when one of the non-threadsafe programs is linked or xctl’ed to, thus serializing the data access. Remember that every program that access any of these non-serialized storage areas must remain QUASIRENT for this process to work correctly; if any program containing a non-serialized storage access is marked as THREADSAFE, then all of the programs accessing that area are at risk.
The second alternative is to move the data.
CICS offers a number of alternatives to shared storage that are fully serialized, including Temporary Storage, DB2 tables, VSAM files, Data Tables and the Coupling Facility. Relocating the offending data to one of these areas will remove the non-threadsafe activity. These areas have the additional benefit of being sharable between regions, thus allowing the removal of a transaction affinity at the same time as making the application threadsafe. For high-use data, the option of CICS Maintained Data Tables is particularly popular, as it provides quick access with less overhead than some of the other options.
The final alternative is to serialize the data.
If the data cannot be moved, then the only other option is to add code to manually serialize access to it. CICS provides the EXEC CICS ENQ/DEQ commands to provide serialization, but they add overhead and can result in deadly embraces. If the decision is made to utilize ENQ/DEQ, care must be taken to follow standard design practices and ensure that multiple areas are serialized on in the same order, and that enqueues are released as soon as is possible. When utilizing enqueues, you need to decide if read-only access to each area must be serialized, or only update access.
A second alternative for serialization is use of the Compare and Swap assembler instruction. CS (and it’s cousin, Compare Double and Swap) provide serialized memory access at the hardware level; for the duration of the CS instruction, no other processor on the machine is allowed to access the storage area in question. Compare and Swap can be confusing the first time it’s used.