|
|
1.1 root 1: /* 1.1.1.2 ! root 2: * Example of DosEnterCritSec/DosExitCritSec usage. 1.1 root 3: * 1.1.1.2 ! root 4: * After a call to DosEnterCritSec, a thread can be sure that it is the 1.1 root 5: * only one in the current process running. 6: * 7: * Note that critical sections, like thread suspensions, are overridden 8: * by signals, so any signal handlers must be written so as not to 9: * affect the resource protected by the critical section. 10: * 1.1.1.2 ! root 11: * The effect of DosEnterCritSec differs from the use of semaphores for 1.1 root 12: * exclusion between threads. Semaphores allow other threads to generally 13: * run, and only blocks them when they hit a locked region. This is the 1.1.1.2 ! root 14: * generally preferable way to write a program. DosEnterCritSec is much 1.1 root 15: * more drastic since it freezes all other threads, regardless of whether 16: * they are in a particular critical section or not. In effect this 17: * function makes the entire program a critical section, and claims it for 18: * one thread. This type of behaviour is rarely needed. 19: * 20: * In this example, one thread is using STDIO (printf()) to write to the 21: * screen, and another thread is using the low level VIO function. Each 22: * thread forces a critical section before writing to the screen to prevent 23: * these two different routines colliding. As described above, this, and 24: * most other critical section problems are better handled with a semaphore. 25: * 26: * compile as: cl -Ox -Zp -AL -Lp critsec.c 27: * 1.1.1.2 ! root 28: * Created by Microsoft Corp. 1986 1.1 root 29: */ 30: 1.1.1.2 ! root 31: #define INCL_SUB ! 32: #define INCL_DOSPROCESS ! 33: ! 34: #include <os2def.h> ! 35: #include <bse.h> 1.1 root 36: #include <stdio.h> 37: #include <malloc.h> 38: #include <assert.h> 39: 40: #define STACK_SIZE 1024 41: 42: void far f_thread(void); 43: int flag; 44: 45: void main() 46: { 1.1.1.2 ! root 47: PCHAR stkptr; ! 48: TID thread_id; ! 49: unsigned res; 1.1 root 50: 51: flag = 0; 52: 53: /* obtain pointer to the END of a block of memory for stack */ 54: stkptr = (char *)malloc(STACK_SIZE) + STACK_SIZE; 55: 56: /* create another thread */ 1.1.1.2 ! root 57: res = DosCreateThread(f_thread, &thread_id, stkptr); 1.1 root 58: assert(res == 0); 59: 60: /* wait for the sub-thread to set the flag */ 61: while (flag == 0) { 1.1.1.2 ! root 62: DosSleep(100L); 1.1 root 63: /* 64: * Remember: testing of the flag must be atomic too. 65: * otherwize the flag will be set !0 between the test and 66: * the printf! 67: */ 1.1.1.2 ! root 68: DosEnterCritSec(); 1.1 root 69: if (flag == 0) 70: printf("Thread 0: flag is still zero\n"); 1.1.1.2 ! root 71: DosExitCritSec(); 1.1 root 72: } 73: 74: printf("Thread 0: flag was finally set\n"); 75: fflush(stdout); 1.1.1.2 ! root 76: DosExit(EXIT_PROCESS,0); 1.1 root 77: } 78: 79: void far f_thread() 80: { 81: /* set the flag */ 1.1.1.2 ! root 82: DosSleep(1000L); ! 83: DosEnterCritSec(); 1.1 root 84: flag = 1; 1.1.1.2 ! root 85: VioWrtTTy("Thread1: I am setting the flag\r\n", 33, 0); ! 86: DosExitCritSec(); 1.1 root 87: 88: /* exit this thread */ 1.1.1.2 ! root 89: DosExit(EXIT_THREAD,0); 1.1 root 90: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.