createCriticalSection

Syntax

int createCriticalSection((void)?)

Arguments

none

Return

Returns a handle to a newly created Critical Section, or 0 if the Critical Section could not be created.

Description

This function creates a new Critical Section, which may be used to enforce mutually exclusive access to a resource or set of resources. At most one thread can "enter" a Critical Section at any given time. Any other threads wishing to enter the same Critical Section must wait until the first thread "leaves" the Critical Section. If you have more that one set of resources that need protection, you can create a separate Critical Section to guard each resource, thus allowing a higher degree of parallel processing, since a thread using one such resource does not lock out other threads from using other guarded resources at the same time.

For more information about Critical Sections, see the MSDN documentation about [Critical Section Objects].

Example

%fml
//
// Sample filter creates 5 worker threads. Each thread is assigned
// the "next available" line "y" to process, until all lines
// have been processed.  Since multiple threads are attempting
// to read and increment the "nextY" variable at the same time,
// we use a Critical Section to serialize access to "nextY".
//
// N.B. This example assumes global variables are implemented in
// such a manner that they are shared among all threads (which is
// not yet true as of FM 1.0 Beta 9e).

int nextY;		//Global int to hold next line to be processed
int csNEXTY;	//Critical Section handle for guarding access to "nextY"

OnCtl(n):{

	if (e==FME_CUSTOMEVENT && n==666) {
		// Perform function #666
		while(1) {

			//Need to serialize access to "nextY"; else
			//two threads may try to increment nextY at
			//the same time, with indeterminate results.

			enterCriticalSection(csNEXTY);
			int y = nextY++;	//"nextY" is a shared global var
			leaveCriticalSection(csNEXTY);

			if (y >= y_end) return true; //exit thread if no more lines to process

			//process this line y...
			for (int x = x_start; x < x_end; x++) {
				for (int z = 0; z < Z; z++) {
					//invert this pixel...
					pset(x,y,z, 255-src(x,y,z));
					//do other useful work here...
				}//for z
			}//for x
		}//while(1)
	}//if FME_CUSTOMEVENT 666

	return false;	//other events not yet processed
}


ForEveryTile:{

	// Create a Critical Section to guard access to nextY
	csNEXTY = createCriticalSection();
	if (!csNEXTY) {
		ErrorOk("Failed to create Critical Section csNEXTY");
		return false;
	}

	// Set initial value of "nextY" to y_start
	nextY = y_start;

	// Start 5 worker threads...
	for (int i=0; i < 5; i++)
		triggerThread(666,FME_CUSTOMEVENT,i);

	// Wait for all threads to finish
	waitForThread(0, INFINITE, 0);

	// Delete the Critical Section
	deleteCriticalSection(csNEXTY);

	return true; //finished processing this tile
}

Also see

System Functions, Critical Section Functions, enterCriticalSection, tryEnterCriticalSection, leaveCriticalSection, deleteCriticalSection

Comments

Everyone can add her comments here about her experiences with this function. Tips for using it are welcome, too.