File:  [OS/2 SDKs] / os2sdk / demos / examples / critsec / critsec.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 12:26:17 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: os2sdk-1988, HEAD
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);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.