Windows CE provides several ways to synchronize threads and access to data by multiple threads. These include the synchronization objects that are typical for a multithreaded operating system: mutex, semaphores, events and critical sections. These synchronization objects may be overkill for protecting access to a single variable. The Interlocked functions can be used to control access to a single 32 bit variable.
The interlocked functions are:
Function Name
Action
InterlockedCompareExchange
Compares two values and writes a third value if they are equal
InterlockedCompareExchangePointer
Compares two values and writes a third value if they are equal
InterlockedDecrement
Decrements a value
InterlockedExchange
Writes a new value to a location
InterlockedExchangeAdd
Adds a value to a location
InterlockedExhangePointer
Writes a new value to a location
InterlockedIncrement
Increments a value
IntelockedTestExchange
Compares two values and writes a third value if they are equal
 
These functions all perform atomic actions on the data, meaning that they perform the action without a context switch during the function handling. The functions work by calling into the kernel which then causes an exception. The action is then handled within the exception handler. The functions change a value that is pointed to by a pointer that is passed in. The pointer must point to a 32 bit value that is 32 bit aligned except for x86 processors (for a discussion on what happens if the pointer is not 32 bit aligned see: Platform Builder: Data Misalignment).
A few examples:
// Global data
DWORD Data = 0;
 
void Foo()
{
    DWORD Result;
    Result = InterlockedIncrement( &Data ); // Result will contain the original value of Data
    Result = InterlockedCompareExchange( &Data, 3, 1 ); // if Data == 1 then Result will be 1 and Data will be set to 3
    Result = InterlockedExhangeAdd( &Data, 6 ); // Result contains the original value of Data and Data will contain Data += 6      
}
 
The Interlocked functions provide a safe and convenient way to write to a variable from multiple threads. I say convenient because these functions don’t require the overhead of other synchronization methods when managing small amounts of data.   If on the other hand, you need to manage changing multiple values, the other synchronization methods may be a better choice.
 
Copyright © 2008 – Bruce Eitman
All Rights Reserved