|
|
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.