This program initializes a thread-storage handle and then starts off several threads which each use the handle to access thread local data. Consistency checks are made within each entry to ts-test, on termination of each thread and on termination of the run-unit. This program takes advantage of the Thread-Local-Storage Section, external data items, exit procedures and basic synchronization to achieve this function.
Source Code
$set reentrant sourceformat(free) copy "cblproto.cpy". ************************************************************ * tstore-main. * * Main routine to initialize tables and kick off threads. * * * ************************************************************ program-id. 'tstore'. environment division. special-names. command-line is cmdln. working-storage section. 78 THREAD-COUNT VALUE 5. 01 tstore-handle cblt-pointer is external. 01 c-0 cblt-x1-compx. 01 foo-item pic 9(9) value 0. 01 thredid pic xxxx comp-5. 01 thread-handle cblt-pointer. 01 thread-entry cblt-ppointer. 01 exitparms cblt-exit-params. thread-local-storage section. 01 filler. 05 tl-count pic x value 'x'. 05 tl-ptr cblt-pointer. linkage section. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division. *> *> Initialize thread table and set up for clean exit *> call "CBL_TSTORE_CREATE" using tstore-handle by value length tstore-item by value h'04' *> *> Set up for clean exit *> move low-values to exitparms set cblte-ep-install-addr to entry 'exitproc' move 0 to c-0 call 'CBL_EXIT_PROC' using c-0 exitparms call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr move THREAD-COUNT to tstore-count set thread-entry to entry "ts-entry" move 1 to thredid perform THREAD-COUNT times call "CBL_THREAD_CREATE_P" using by value thread-entry by reference thredid by value length of thredid by value 0 by value 0 by value 0 by reference thread-handle if return-code not = 0 call 'CBL_THREAD_PROG_LOCK' display "FAIL: Cannot create thread" call 'CBL_THREAD_PROG_UNLOCK' stop run end-if add 1 to thredid end-perform stop run. entry "exitproc". call "CBL_TSTORE_GET" using by value tstore-handle by reference tl-ptr set address of tstore-item to tl-ptr if tl-ptr = NULL or not TSTORE-INIT or tstore-count not = THREAD-COUNT display "FAIL: TSTORE not initialized properly!" else display "PASS: Main thread has count " tstore-count end-if call "CBL_TSTORE_CLOSE" using by value tstore-handle exit program. end program 'tstore'. ************************************************************ * * * ts-entry. * * Root entry point for threads created by application. * * * ************************************************************ program-id. 'ts-entry'. working-storage section. 78 REP-COUNT VALUE 5. 01 tl-ptr cblt-pointer. linkage section. 01 lnk-thredid pic xxxx comp-5. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division using lnk-thredid. thread-section. perform REP-COUNT times call 'ts-test' using lnk-thredid end-perform call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr call "CBL_THREAD_PROG_LOCK" if tstore-count not = REP-COUNT display "FAIL: Thread storage rep-count BAD" else display "PASS: Thread storage rep-count good" end-if call "CBL_THREAD_PROG_UNLOCK" exit program. end program 'ts-entry'. ************************************************************ * * * ts-test. * * Routine to get a thread storage area and increment its * * count * * * ************************************************************ program-id. 'ts-test'. working-storage section. 01 global-count pic 99999 value 0. thread-local-storage section. 01 tl-ptr cblt-pointer. 01 tl-count pic 999 value 0. linkage section. 01 lnk-thredid pic xxxx comp-5. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. procedure division using lnk-thredid. thread-section. call 'ts-get' using tl-ptr set address of tstore-item to tl-ptr add 1 to tstore-count add 1 to tl-count if tstore-count not = tl-count display "ERROR: inconsistent thread local data" stop run end-if call "CBL_THREAD_PROG_LOCK" add 1 to global-count display "MESSAGE: thread-test has been called " tstore-count " by thread " lnk-thredid display "MESSAGE: thread-test has been called " global-count " globally " call "CBL_THREAD_PROG_UNLOCK" exit program. end program 'ts-test'. ************************************************************ * ts-get. * * Common routine to get and initialize the thread storage * * area allocated by CBL_TSTORE_GET. * * * ************************************************************ program-id. 'ts-get'. data division. working-storage section. 01 tstore-handle cblt-pointer external. thread-local-storage section. 01 tl-ptr cblt-pointer. linkage section. 01 tstore-item. 05 filler pic x. 88 TSTORE-INIT VALUE 'Y'. 05 tstore-count pic 999. 01 lnk-ptr usage pointer. procedure division using lnk-ptr. call "CBL_TSTORE_GET" using by value tstore-handle by reference tl-ptr if tl-ptr = NULL display "FAIL: Error in getting thread " & "storage data" stop run end-if set address of tstore-item to tl-ptr if not TSTORE-INIT move 0 to tstore-count end-if set tstore-init to true set lnk-ptr to tl-ptr exit program. end program 'ts-get'.