Microsoft KB Archive/37480

From BetaArchive Wiki

COBOL 3.00 Program: Creating Threads in OS/2 Protected Mode

PSS ID Number: Q37480 Article last modified on 06-24-1993

3.00 3.00a | 3.00 3.00a MS-DOS | OS/2

Summary: Microsoft COBOL Version 3.00 or 3.00a can create and use MS OS/2 threads by calling API (Applications Program Interface) routines in MS OS/2 protected mode. The following example demonstrates how to create an MS OS/2 thread: 1. Compile the first thread as follows: PCOBOL THREAD1; 2. Link the first thread as follows: LINK THREAD1 /NOP,,,PCOBOL+DOSCALLS; 3. Compile the second thread as follows: PCOBOL THREAD2; 4. Create a .DEF file. See the THREAD2.DEF example below. 5. Create the Dynamic Link Library as follows: LINK THREAD2 /NOP,,,PCOBOL+DOSCALLS,THREAD2.DEF; 6. Move the new THREAD2.DLL to a directory specified by the LIBPATH= variable that resides in the CONFIG.SYS or CONFIG.OS2 file. 7. Run the threads by executing THREAD1.EXE.

More Information: The following is a code example:



                            • THREAD1.EXE ************** ********************************************************************* $SET OSVS ANS85 *************************************************************** * THREAD1 - Demonstration of using multiple threads in a COBOL * program. This program will start THREAD2.DLL as a separate thread * which runs concurrently. ************************************************************** WORKING-STORAGE SECTION. 01 DosLoadModule-Parameters. 03 Obj-Name-Buf PIC X(10). 03 Obj-Name-Buf-Length PIC 9(4) COMP-5 VALUE 10. 03 Module-Name. 03 FILLER PIC X(7) VALUE “THREAD2”. 03 FILLER PIC 9(2) COMP-5 VALUE 0. 03 Module-Handle PIC 9(4) COMP-5. 01 Thread2-Address USAGE IS POINTER. 01 Stack-Pointer USAGE IS POINTER. 01 Thread2-Stack. 03 FILLER PIC X(511). 03 Thread2-Stack-Top PIC X. 01 Thread2-ID PIC 9(4) COMP-5. 01 VioWrtCharStr-Parameters. 03 Char-Str-Length PIC 9(4) COMP-5 VALUE 8. 03 Char-Str-Start-Row PIC 9(4) COMP-5 VALUE 10. 03 Char-Str-Start-Col PIC 9(4) COMP-5 VALUE 12. 03 Vio-Handle PIC 9(4) COMP-5 VALUE 0. 01 Semaphore-Parameters. 03 Not-Exclusive PIC 9(4) COMP-5 VALUE 1. 03 Semaphore-Handle PIC 9(8) COMP-5. 03 Semaphore-Name. 03 FILLER PIC X(12) VALUE “”. 03 FILLER PIC 9(5) COMP-5 VALUE 0. 03 Timeout PIC X(4) VALUE X“FFFFFFFF”. 01 Disp-Return-Code PIC 9(5). 01 Display-Counter PIC 9(8). PROCEDURE DIVISION. Thread1 SECTION. * Clear screen CALL X“E4” * Load THREAD2.DLL into memory and get a handle for it. CALL “P_DOSLOADMODULE” USING BY REFERENCE Obj-Name-Buf BY VALUE Obj-Name-Buf-Length BY REFERENCE Module-Name BY REFERENCE Module-Handle IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosLoadModule failed - Return code =” Disp-Return-Code GO TO Thread1-Exit. * Get the address of the first instruction in THREAD2. CALL “P_DOSGETPROCADDR” USING BY VALUE Module-Handle BY REFERENCE Module-Name BY REFERENCE Thread2-Address IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosGetProcAddr failed - Return code=” Disp-Return-Code GO TO Thread1-Exit. * Create a system semaphore that is used by THREAD2 to * indicate that it has completed. CALL “P_DOSCREATESEM” USING BY VALUE Not-Exclusive BY REFERENCE Semaphore-Handle BY REFERENCE Semaphore-Name IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosCreateSem failed - Return code =” Disp-Return-Code GO TO Thread1-Exit. * Set up the stack pointer for THREAD2. SET Stack-Pointer TO ADDRESS OF Thread2-Stack-Top * Start THREAD2 off as a concurrent thread. CALL “P_DOSCREATETHREAD” USING BY VALUE Thread2-Address BY REFERENCE Thread2-ID BY VALUE Stack-Pointer IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosCreateThread failed- Return code=” Disp-Return-Code GO TO Thread1-Exit. MOVE 1 TO Display-Counter. PERFORM UNTIL Display-Counter = 10000 CALL “P_VIOWRTCHARSTR” USING BY REFERENCE Display-Counter BY VALUE Char-Str-Length BY VALUE Char-Str-Start-Row BY VALUE Char-Str-Start-Col BY VALUE Vio-Handle ADD 1 TO Display-Counter END-PERFORM. * Wait for THREAD2 to finish. CALL “P_DOSSEMSETWAIT” USING BY VALUE Semaphore-Handle BY VALUE Timeout IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosSemSetWait failed - Return code =” Disp-Return-Code GO TO Thread1-Exit. * THREAD2 has finished, so you can dispose of the semaphore. CALL “P_DOSCLOSESEM” USING BY VALUE Semaphore-Handle IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread1 : DosCloseSem failed - Return code =” Disp-Return-Code. Thread1-Exit. STOP RUN.



                            • THREAD2.EXE ************** ********************************************************************* $SET OSVS ANS85 *************************************************************** * THREAD2. This should be linked as a DLL and placed in a * directory on the LIBPATH. *************************************************************** WORKING-STORAGE SECTION. 01 DosExit-Parameters. 03 End-Current-Thread PIC 9(4) COMP-5 VALUE 0. 03 Dos-Exit-Return-Code PIC 9(4) COMP-5 VALUE 0. 01 VioWrtCharStr-Parameters. 03 Char-Str-Length PIC 9(4) COMP-5 VALUE 8. 03 Char-Str-Start-Row PIC 9(4) COMP-5 VALUE 10. 03 Char-Str-Start-Col PIC 9(4) COMP-5 VALUE 60. 03 Vio-Handle PIC 9(4) COMP-5 VALUE 0. 01 Semaphore-Parameters. 03 Semaphore-Handle PIC 9(8) COMP-5. 03 Semaphore-Name. 03 FILLER PIC X(12) VALUE “”. 03 FILLER PIC 9(5) COMP-5 VALUE 0. 01 Display-Counter PIC 9(8). 01 Disp-Return-Code PIC 9(5). PROCEDURE DIVISION. Thread2 SECTION. * Open the semaphore created by THREAD1 to make sure you have * access to it. CALL “P_DOSOPENSEM” USING BY REFERENCE Semaphore-Handle BY REFERENCE Semaphore-Name IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread2 : DosOpenSem failed - Return code =” Disp-Return-Code GO TO Thread2-Exit. MOVE 1 TO Display-Counter. PERFORM UNTIL Display-Counter = 10000 CALL “P_VIOWRTCHARSTR” USING BY REFERENCE Display-Counter BY VALUE Char-Str-Length BY VALUE Char-Str-Start-Row BY VALUE Char-Str-Start-Col BY VALUE Vio-Handle ADD 1 TO Display-Counter END-PERFORM * Tell THREAD1 that you have finished. CALL “P_DOSSEMCLEAR” USING BY VALUE Semaphore-Handle IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread2 : DosSemClear failed - Return code =” Disp-Return-Code GO TO Thread2-Exit. * Finish with semaphore. CALL “P_DOSCLOSESEM” USING BY VALUE Semaphore-Handle IF RETURN-CODE NOT = 0 MOVE RETURN-CODE TO Disp-Return-Code DISPLAY “Thread2 : DosCloseSem failed - Return code =” Disp-Return-Code. Thread2-Exit. CALL “P_DOSEXIT” USING BY VALUE End-Current-Thread BY VALUE Dos-Exit-Return-Code.



                            • THREAD2.DEF ************** ********************************************************************* ; Module definition file for THREAD2 LIBRARY INITINSTANCE ; THREAD2 is a dynamic link library. PROTMODE ; It needs to run in protected mode. DATA NONSHARED ; It expects OS/2 to duplicate data areas ; for each task. CODE LOADONCALL ; Since it is transient, load when needed. EXPORTS THREAD2 @1 ; It assumes that the PROGRAM-ID is THREAD2.

Copyright Microsoft Corporation 1993.