Microsoft KB Archive/37480

From BetaArchive Wiki
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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.