NT Critical Section

[Back]

NT provides four types of synchronization objects: critical sections, semaphores, mutexes, and events: Technically the first three are all instances of the general semaphore, as discussed in class.  The instance known as Critical_Section is NT's version of an intra-process binary semaphore. Below are the prototype APIs that are required followed by an example (I used cut-n-paste, so it does compile in VC++, with project | setting | C/C++ | code generation | run-time==multithreaded).
 
#include <windows.h>
 
Critical_Section  cs;
 
InitializeCriticalSection( &cs);        /* setup binary semaphore */
EnterCriticalSection( &cs);
LeaveCriticalSection( &cs);
DeleteCriticalSection( &cs);

EXAMPLE:

#include <stdio.h>
#include <stdlib.h> /* rand() */
#include <process.h> /* _beginthread */
#include <windows.h> /* CRITICAL_SECTION */
#include <conio.h> /* _getch() */

#define GetRandom( min, max ) ((rand() % (int)(((max) + 1) - (min))) + (min))

#define N                    ( (int)100)

#define PROTECTED 0                       /* yes==1, no==0 */

#if PROTECTED 
 CRITICAL_SECTION cs; 
#endif

 int counter=0;                                  /* shared variable */

 bool wait=true;


void CPU( void * delta)                          /* simulate a two register CPU */

register int reg1, reg2;
#if PROTECTED
 EnterCriticalSection( &cs);                           /* option to lock area */
#endif

 reg1 = (int) delta;                                       /* cpu register 1 <- copy delta */
 reg2 = counter;                                          /* cpu register 2 <- copy counter */ 
 Sleep( GetRandom(0,10) );                         /* simulate random interruts of CPU */
 reg2 = reg2 + reg1;                                    /* register-register addition */
 counter = reg2;                                          /* copy register to RAM */

#if PROTECTED
  LeaveCriticalSection( &cs);             /* option to unlock area */
#endif

  printf("count is %d\n", counter);
}


void CheckKey( void *dummy )              /* deamon process to look for a pressed */
{ /* key, any key. */
  _getch();
  wait = false;
}


void main() {

int i, sum = (N*(N-1))/2;

#if PROTECTED
       InitializeCriticalSection( &cs);                                 /* setup binary semaphore */
#endif

_beginthread(CheckKey, 0, NULL);                          /* start background thread */

for(i=0; i<N; i++)
_beginthread(CPU, 0, (void *) i);                            /* give each CPU marching orders */

while (wait )                                             /* check if deamon has found a pressed key */
                      Sleep(100L);                       /* take a nap between ... */ 

printf("totla should be %d, and is computed as %d\n", sum, counter);

}