A.2_Threading
A.2 Threading
chLib includes a minimalist threading library that enables the creation of a pool of "worker" CPU threads, plus facilities that enable a parent thread to "delegate" work onto worker threads. Threading is a particularly difficult feature to abstract, since different operating systems have such different facilities to enable it. Some
operating systems even have "thread pools" that enable threads to be easily recycled, so applications don't have to keep threads suspended waiting for a synchronization event that will be signaled when some work comes along.
Listing A.1 gives the abstract threading support from chLib/chThread.h. It includes a processorCount() function that returns the number of CPU cores available (many applications that use multiple threads to take advantage of multiple CPU cores, such as our multithreaded N-body implementation in Chapter 14, want to spawn one thread per core) and a C++ class workerThread that enables a few simple threading operations.
Creation and destruction
delegateSynchronous(): the parent thread specifies a pointer to function for the worker to execute, and the function does not return until the worker thread is done.
delegateAsynchronous(): the parent thread specifies a pointer to function for the worker to run asynchronously; workerThread::waitAll must be called in order to synchronize the parent with its children.
The member function waitAll() waits until all specified worker threads have completed their delegated work.
Listing A.1 workerThread class.
//
// Return the number of execution cores on the platform.
//
unsigned int processorCount();
//
// workerThread class - includes a thread ID (specified to constructor)
//
class workerThread
{
public: workerThread( int cpuThreadId = 0 ); virtual ~workerThread(); bool initialize(); // thread routine (platform specific) static void threadRoutine( LPVOID ); // call this from your app thread to delegate to the worker. // it will not return until your pointer-to-function has been called with the given parameter.bool delegateSynchronous(void (*pfn)(void *), void *parameter); // // call this from your app thread to delegate to the worker // asynchronously. Since it returns immediately, you must call // await all later bool delegateAsynchronous(void (*pfn)(void *), void *parameter); static bool awaitAll( workerThread *p, size_t N );
};