User Guide

Introduction

This document provides a brief description of the EAThread modules and then provides some basic information on using these modules. You will want to consult documentation for individual modules for more detailed information about them.

All code is in C++ and largely follows the EA coding guidelines as of January of 2004. All classes are in the EA::Thread C++ namespace. Thus, the fully qualified name of the Mutex class is EA::Thread::Mutex. Most of the code is plain C++ and doesn't attempt to be very academic with the language. Thus RTTI is not used, template usage is used only in one module (FixedAllocator), exception handling is not used, etc. Unit tests have been set up for most of the functionality and are available with the full package. The headers are heavily commented in Doxygen-savvy format and the source code for the primary modules has been heavily commented as well.

EAThread Modules

Module
Description Source
Dependencies
Thread
Implements the creation and control of individual threads.
eathread.h/cpp
eathread_thread.h/cpp
EABase
Storage
Implements thread-specific storage (a.k.a. thread-local storage). This is a mechanism whereby a given named global variable exists not once globally but exists once per thread. Each thread gets its own view of the variable.
eathread_storage.h/cpp
EABase
eathead.h/cpp
eathread_mutex.h/cpp*

Atomic Implements atomic operations on integers and pointers. These are useful for doing thread-safe basic operations and tests on integers or pointers without the cost of more expensive synchronization primitives such as mutexes.
eathread_atomic.h
EABase
Mutex
Implements traditional mutual exclusion. Mutexes here encompass critical section functionality (a.k.a. futex) and traditional cross-process exclusion.
eathread_mutex.h/cpp
EABase
eathread.h/cpp
Futex Implements a fast mutex. A fast mutex is a mutex which can be faster because it acts entirely within user space within the current process and can possibly have some of its code inlined. eathread_futex.h/cpp EABase
eathread.h/cpp
ReadWriteMutex
Implements a mutex that allows multiple concurrent reading threads but only one writing thread. This is useful for situations where one thread is updating a state but multiple threads may be reading that state.
eathread_rwmutex.h/cpp
EABase
eathread.h/cpp
eathread_atomic.h
eathread_condition.h/cpp
Semaphore
Implements a traditional sempahore. A semaphore has zero or positive count associated with it; a thread can 'grab' the semaphore if the count is greater than zero and grabbing it reduces its count by one. When the count is zero, threads must wait until it is incremented, which can be done arbitrarily. The semaphore is the primitive upon which all other high level primitives can be constructed.
eathread_semaphore.h/cpp
EABase
eathread.h/cpp
eathread_atomic.h
Condition
Implements a condition variable, which is a synchronization primitive that supports the producer/consumer pattern. It is for all practical purposes also known as a "monitor" in Java and C#. This primitive is particularly useful for implementing efficient cross thread-messaging systems or worker thread job implementations.
eathread_condition.h/cpp
EABase
eathread.h/cpp
eathread_atomic.h
eathread_mutex.h/cpp eathread_semaphore.h/cpp
Barrier
Implements a cyclic barrier primitive. A barrier is a primitive which coordinates the completion of work by a predetermined number of threads. A barrier has an integer max "height" and a current height associated with it. When a thread hits the barrier, it blocks until the prescribed number of threads hit the barrier, then all are freed.
eathread_barrier.h/cpp

EABase
eathread.h/cpp
eathread_atomic.h
eathread_semaphore.h/cpp

SpinLock
Implements a traditional spin lock. A spin lock is a special kind of mutex that "spins" in a loop waiting to be able to continue instead of blocking like a mutex. A spinlock is more efficient than a mutex but it generally doesn't work unless operating on a true multi-processing system. When it does work on a true multi-processing system it is inefficient.
eathread_spinlock.h
EABase
eathread.h/cpp
eathread_sync.h
eathread_atomic.h
ReadWriteSpinLock
Implements a spinlock that allows multiple readers but only a single writer. Otherwise it is similar to a basic spin lock with respect to purpose and applicability.
eathread_rwspinlock.h
EABase
eathread.h/cpp
eathread_sync.h
eathread_atomic.h
ThreadPool
Implements a "pool" of worker threads available for work. These are commonly used by server systems to spawn off client-server tasks.
eathread_pool.h/cpp
EABase
eathread.h/cpp
eathread_thread.h/cpp
eathread_condition.h/cpp
eathread_atomic.h
eathread_list.h
Sync
Implements memory synchronization primitives known as "fences" or "barriers" (not to be confused with thread barrier primitives). These primitives are useful on multiprocessing platforms for synchronizing the various processors' view of memory, which can become "unsynchronized" in the presence of per-processor caches.
eathread_sync.h
EABase
shared_ptr_mt
shared_array_mt
These are multithread-safe equivalents to regular smart pointers such as shared_ptr and shared_array. See the TL (Template Library) for implementations of the regular versions of these smart pointers.
shared_ptr_mt.h
shared_array_mt.h

eathread_atomic.h
eathread_mutex.h

* May not be required, depending on your platform/configuration.

Examples

We present some very basic examples of how to use some of the EAThread modules. These exemplify the simplest uses of these modules and don't go into more advanced or complicated uses. There is more functionality in each of the classes than shown; see the documentation or header files for more information. For clarity, the examples assume that the code has specified the using EA::Thread; namespace statement.

How to create a thread.

#include "eathread/eathread_thread.h"

int ThreadFunction(void* pContext){
   return 0;
}

Thread thread;
thread.Begin(ThreadFunction);

How to use thread-local storage.

#include "eathread/eathread_storage.h"

ThreadLocalStorage tls;
tls.SetValue("hello");
const char* pString = (const char*)tls.GetValue();

How to create and use an atomic integer.

#include "eathread/eathread_atomic.h"

AtomicInteger i = 5;
i += 7;
--i;
if(i.SetValueConditional(3, 6))
   printf("i was 6 and now is 3.");

How to create and use a mutex.

#include "eathread/eathread_mutex.h"

Mutex mutex(NULL, true);
mutex.Lock();
mutex.Unlock();

How to create and use a futex.

#include "eathread/eathread_futex.h"

Futex futex;
futex.Lock();
futex.Unlock();

How to create and use a semaphore.

#include "eathread/eathread_semaphore.h"

Semaphore semaphore(NULL, true);
semaphore.Post();
semaphore.Wait();

How to create and use a condition variable.

#include "eathread/eathread_condition.h"

Condition condition(NULL, true);
Mutex     mutex(NULL, true);
condition.Signal();
condition.Wait(&mutex);

How to create and use a spin lock.

#include "eathread/eathread_spinlock.h"

SpinLock spinLock;
spinLock.Lock();
spinLock.Unlock();

How to create and use a shared_ptr_mt.

#include "eathread/shared_ptr_mt.h"

shared_ptr_mt pObject(new SomeClass);
pObject->DoSomething();


End of document