|
|
Microsoft OS/2 SDK 03-01-1988
/*
* Example of DosEnterCritSec/DosExitCritSec usage.
*
* After a call to DosEnterCritSec, a thread can be sure that it is the
* only one in the current process running.
*
* Note that critical sections, like thread suspensions, are overridden
* by signals, so any signal handlers must be written so as not to
* affect the resource protected by the critical section.
*
* The effect of DosEnterCritSec differs from the use of semaphores for
* exclusion between threads. Semaphores allow other threads to generally
* run, and only blocks them when they hit a locked region. This is the
* generally preferable way to write a program. DosEnterCritSec is much
* more drastic since it freezes all other threads, regardless of whether
* they are in a particular critical section or not. In effect this
* function makes the entire program a critical section, and claims it for
* one thread. This type of behaviour is rarely needed.
*
* In this example, one thread is using STDIO (printf()) to write to the
* screen, and another thread is using the low level VIO function. Each
* thread forces a critical section before writing to the screen to prevent
* these two different routines colliding. As described above, this, and
* most other critical section problems are better handled with a semaphore.
*
* compile as: cl -Ox -Zp -AL -Lp critsec.c
*
* Created by Microsoft Corp. 1986
*/
#define INCL_SUB
#define INCL_DOSPROCESS
#include <os2def.h>
#include <bse.h>
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#define STACK_SIZE 1024
void far f_thread(void);
int flag;
void main()
{
PCHAR stkptr;
TID thread_id;
unsigned res;
flag = 0;
/* obtain pointer to the END of a block of memory for stack */
stkptr = (char *)malloc(STACK_SIZE) + STACK_SIZE;
/* create another thread */
res = DosCreateThread(f_thread, &thread_id, stkptr);
assert(res == 0);
/* wait for the sub-thread to set the flag */
while (flag == 0) {
DosSleep(100L);
/*
* Remember: testing of the flag must be atomic too.
* otherwize the flag will be set !0 between the test and
* the printf!
*/
DosEnterCritSec();
if (flag == 0)
printf("Thread 0: flag is still zero\n");
DosExitCritSec();
}
printf("Thread 0: flag was finally set\n");
fflush(stdout);
DosExit(EXIT_PROCESS,0);
}
void far f_thread()
{
/* set the flag */
DosSleep(1000L);
DosEnterCritSec();
flag = 1;
VioWrtTTy("Thread1: I am setting the flag\r\n", 33, 0);
DosExitCritSec();
/* exit this thread */
DosExit(EXIT_THREAD,0);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.