|
|
1.1 ! root 1: /* ! 2: * Example of DOSENTERCRITSEC/DOSEXITCRITSEC usage. ! 3: * ! 4: * After a call to DOSENTERCRITSEC, a thread can be sure that it is the ! 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: * ! 11: * The effect of DOSENTERCRITSEC differs from the use of semaphores for ! 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 ! 14: * generally preferable way to write a program. DOSENTERCRITSEC is much ! 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: * ! 28: * Copyright (C) Microsoft Corp. 1986 ! 29: */ ! 30: ! 31: #include <doscalls.h> ! 32: #include <subcalls.h> ! 33: #include <stdio.h> ! 34: #include <malloc.h> ! 35: #include <assert.h> ! 36: ! 37: #define STACK_SIZE 1024 ! 38: ! 39: void far f_thread(void); ! 40: int flag; ! 41: ! 42: void main() ! 43: { ! 44: char far *stkptr; ! 45: unsigned thread_id, res; ! 46: ! 47: flag = 0; ! 48: ! 49: /* obtain pointer to the END of a block of memory for stack */ ! 50: stkptr = (char *)malloc(STACK_SIZE) + STACK_SIZE; ! 51: ! 52: /* create another thread */ ! 53: res = DOSCREATETHREAD(f_thread, &thread_id, stkptr); ! 54: assert(res == 0); ! 55: ! 56: /* wait for the sub-thread to set the flag */ ! 57: while (flag == 0) { ! 58: DOSSLEEP((long)100); ! 59: /* ! 60: * Remember: testing of the flag must be atomic too. ! 61: * otherwize the flag will be set !0 between the test and ! 62: * the printf! ! 63: */ ! 64: DOSENTERCRITSEC(); ! 65: if (flag == 0) ! 66: printf("Thread 0: flag is still zero\n"); ! 67: DOSEXITCRITSEC(); ! 68: } ! 69: ! 70: printf("Thread 0: flag was finally set\n"); ! 71: fflush(stdout); ! 72: DOSEXIT(1,0); ! 73: } ! 74: ! 75: void far f_thread() ! 76: { ! 77: /* set the flag */ ! 78: DOSSLEEP((long)1000); ! 79: DOSENTERCRITSEC(); ! 80: flag = 1; ! 81: VIOWRTTTY("Thread1: I am setting the flag\r\n", 33, 0); ! 82: DOSEXITCRITSEC(); ! 83: ! 84: /* exit this thread */ ! 85: DOSEXIT(0,0); ! 86: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.