Mutexes in COBOL

In the previous example, we saw how to manage simple counter state using atomic operations. For more complex state, we can use a mutex to safely access data across multiple threads.

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MUTEXES.
       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-CONTAINER.
           05 WS-COUNTERS.
               10 WS-COUNTER-A PIC 9(5) VALUE 0.
               10 WS-COUNTER-B PIC 9(5) VALUE 0.
       01 WS-MUTEX SYNC.

       PROCEDURE DIVISION.
       MAIN-PROCEDURE.
           PERFORM INITIALIZE-CONTAINER
           PERFORM START-THREADS
           PERFORM DISPLAY-RESULTS
           STOP RUN.

       INITIALIZE-CONTAINER.
           MOVE 0 TO WS-COUNTER-A
           MOVE 0 TO WS-COUNTER-B.

       START-THREADS.
           CALL "CBL_CREATE_THREAD" USING 
               THREAD-MAIN-A
               BY REFERENCE WS-CONTAINER
               BY REFERENCE WS-MUTEX.
           CALL "CBL_CREATE_THREAD" USING 
               THREAD-MAIN-A
               BY REFERENCE WS-CONTAINER
               BY REFERENCE WS-MUTEX.
           CALL "CBL_CREATE_THREAD" USING 
               THREAD-MAIN-B
               BY REFERENCE WS-CONTAINER
               BY REFERENCE WS-MUTEX.
           CALL "CBL_WAIT_ON_MULTIPLE_THREADS" USING 3.

       DISPLAY-RESULTS.
           DISPLAY "Counter A: " WS-COUNTER-A
           DISPLAY "Counter B: " WS-COUNTER-B.

       THREAD-MAIN-A.
           PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10000
               PERFORM INCREMENT-A
           END-PERFORM.

       THREAD-MAIN-B.
           PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10000
               PERFORM INCREMENT-B
           END-PERFORM.

       INCREMENT-A.
           CALL "CBL_ENTER_CRITICAL_SECTION" USING WS-MUTEX
           ADD 1 TO WS-COUNTER-A
           CALL "CBL_EXIT_CRITICAL_SECTION" USING WS-MUTEX.

       INCREMENT-B.
           CALL "CBL_ENTER_CRITICAL_SECTION" USING WS-MUTEX
           ADD 1 TO WS-COUNTER-B
           CALL "CBL_EXIT_CRITICAL_SECTION" USING WS-MUTEX.

In this COBOL program, we define a container structure (WS-CONTAINER) that holds two counters. Since we want to update it concurrently from multiple threads, we add a mutex (WS-MUTEX) to synchronize access.

The INCREMENT-A and INCREMENT-B procedures lock the mutex before accessing the counters and unlock it afterward. This ensures that only one thread can modify the counters at a time.

In the START-THREADS procedure, we create three threads: two that increment counter A and one that increments counter B. We use the CBL_CREATE_THREAD call to start the threads and CBL_WAIT_ON_MULTIPLE_THREADS to wait for them to finish.

Note that the zero value of a mutex is usable as-is in COBOL, so no initialization is required.

Running the program shows that the counters are updated as expected:

Counter A: 20000
Counter B: 10000

This example demonstrates how to use mutexes to safely manage shared state across multiple threads in COBOL. While COBOL doesn’t have built-in goroutines like Go, we can achieve similar concurrency using threads and synchronization primitives.

Next, we’ll look at implementing this same state management task using only threads and message passing.