This column originally appeared on TechTarget's Expert Answer Center as a post in Robert Crawford's blog. Robert served as the on-demand expert on the Expert Answer Center for two weeks in January to February 2006, during which he was available to quickly answer questions on CICS application performance and design, as well as to write daily blog entries. Keep an eye on the Expert Answer Center for topics that could help your IT shop.
IBM introduced the concept of being threadsafe a couple of versions ago. While IBM itself is struggling to make CICS compliant, we've used it to great advantage for one of our larger applications. Since the application is in C++, which is by default threadsafe unless you break one of the rules, we're able to shove three or four transactions per second through an application owning region (AOR) that would otherwise be single-threaded. However, there remains a bit of mystery surrounding what it means to be threadsafe.
In the old days CICS programs just had to be quasi-reentrant, which was a strange concept even for CICS. Remember that standard CICS programs all run under a single quasi-reentrant TCB (QR TCB). In addition, because CICS is a cooperative multitasking environment, a program won't lose control of the CPU until it issues a CICS command that incurs a wait or the runaway task timer pops. This meant that a non-reentrant CICS program could successfully multitask as long any changes to program memory were undone before the task lost control of the processor. This seemed to work well for decades, especially when programmers kept their fingers crossed.
However, IBM recognized a weakness in CICS' single TCB structure and set out to address the situation. First off, they created a new TCB structure that isolated some system functions. Then they got rid of the macro API, which also stopped customers from meddling in system control blocks. Next IBM came up with the open TCB's for Java, SSL, sockets and DB2.
Now, when an application makes a DB2 call, CICS dispatches it on one of the DB2 open (L8) TCBs to do the heavy lifting of the database call is done. If control returns to a quasi-reentrant program, CICS redispatches it in the QR TCB. However, if the program is threadsafe, it continues executing on the L8 TCB. The task will stay on the L8 TCB until it links to a quasi-reentrant program or issues a non-threadsafe CICS command.
Running under the open TCB accomplishes a couple of things. First, it allows more work to get done in one CICS address space. Before, everyone had to wait their turn in the QR dispatching chain. Now, each task runs independently and takes its chances with the MVS dispatcher. Second, it avoids some of the pitfalls of making operating system calls from CICS. Since the task is on its own TCB it can issue OS waits, posts or file I/O, although I wouldn't recommend it.
Of course, the really important question is: How can you tell if a program is threadsafe? The answer is there's no easy way. Re-entrancy is a good start, but not an absolute guarantee. There may also be some technique buried deep within the code that violates threadsafe requirements. By way of example, a few weeks ago our programmers were volume testing a supposedly threadsafe application, but couldn't get the rate past three or four transactions per second before the abends started. I looked through the dump and found a parameter list inside of a program instead of dynamic storage. It turns out the threadsafe application called a PL/1 utility that had the parameter list in static memory. Right now they're in the process of recompiling and testing the utility.
IBM has a way to go, too. The CICS Application Programming Reference lists the threadsafe commands. You may notice a lot of your favorites aren't in there. I'm assuming IBM will make the commands threadsafe as they move more and more support into functional domains.
Despite its slow adoption threadsafe programs are the way to go. Not only will one CICS address space be able to do more work, some current application programming restrictions may be lifted. CICS/TS 3.1 takes a further step in that direction by executing threadsafe programs on open TCBs with or without DB2 calls. But, to get there, you have to remain calm, go through your code very carefully, perform stress tests and don't assume you got it right the first time.