JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.
If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.
If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.
| CodeSonar® 9.0p0 Hot Tips | CONFIDENTIAL | CodeSecure Inc |
Concurrency libraries may reduce or eliminate the risk of data races by guaranteeing certain properties: for example, that a particular operation is atomic, or that two different threads will never use the same memory location. CodeSonar concurrency models can account for these properties.
Extension API prototype csonar_relay_ignore() is provided so that you can indicate to the CodeSonar analysis that one or more specific global or file-static variables are exempt from data race checking.
The shipped CodeSonar library models use this mechanism to exclude special variable errno from data race checks. Modern C compilers give each thread its own copy of errno.
Data located in thread-local storage cannot be subject to data race problems, since only one thread is accessing the data.
CodeSonar ships with library models that allow it to recognize a number of operators and functions that set values in thread-local storage. Some examples are listed below.
| Functions recognized as setting values in thread-local storage include... | |
|---|---|
| Apache Portable Runtime (APR) | apr_threadkey_private_set() |
| FreeRTOS | vTaskSetThreadLocalStoragePointer() |
| libc | g_private_set() |
| Netscape Portable Runtime (NSPR) | PR_SetThreadPrivate() |
| Win32 | TlsAlloc() |
CodeSonar ships with library models that allow it to recognize a number of operators and functions that get values in thread-local storage. Some examples are listed below.
| Functions recognized as setting values in thread-local storage include... | |
|---|---|
| Apache Portable Runtime (APR) | apr_threadkey_private_get() |
| FreeRTOS | pvTaskGetThreadLocalStoragePointer() |
| libc | g_private_get() |
| Netscape Portable Runtime (NSPR) | PR_GetThreadPrivate() |
| Win32 | TlsGetValue() |
When a particular block of code is guaranteed to be atomic (that is, to execute without interruption), memory reads and writes within that block will not participate in any data races and can be excluded from data race checks. CodeSonar models the following Win32 functions as atomic.
| Win32 | |
|---|---|
| InterlockedBitTestAndComplement() | |
| InterlockedBitTestAndComplement64() | |
| InterlockedBitTestAndReset() | |
| InterlockedBitTestAndResetAcquire() | |
| InterlockedBitTestAndResetRelease() | |
| InterlockedBitTestAndReset64() | |
| InterlockedBitTestAndSet() | |
| InterlockedBitTestAndSetAcquire() | |
| InterlockedBitTestAndSetRelease() | |
| InterlockedBitTestAndSet64() | |
| InterlockedCompareExchange() | |
| InterlockedCompareExchangeAcquire() | |
| InterlockedCompareExchangeRelease() | |
| InterlockedCompareExchangeNoFence() | |
| InterlockedCompareExchange16() | |
| InterlockedCompareExchange16Acquire() | |
| InterlockedCompareExchange16Release() | |
| InterlockedCompareExchange16NoFence() | |
| InterlockedCompareExchange64() | |
| InterlockedCompareExchange64Acquire() | |
| InterlockedCompareExchange64Release() | |
| InterlockedCompareExchange64NoFence() | |
| InterlockedCompareExchangePointer() | |
| InterlockedCompareExchangePointerAcquire( | |
| InterlockedCompareExchangePointerRelease() | |
| InterlockedCompareExchangePointerNoFence() | |
| InterlockedCompareExchange128() | |
| InterlockedCompare64Exchange128() | |
| InterlockedCompare64ExchangeAcquire128() | |
| InterlockedCompare64ExchangeRelease128() | |
| InterlockedCompare64ExchangeNoFence128() | |
| InterlockedDecrement() | |
| InterlockedDecrement() | |
| InterlockedDecrementRelease() | |
| InterlockedDecrementNoFence() | |
| InterlockedDecrement16() | |
| InterlockedDecrement16Acquire() | |
| InterlockedDecrement16Release() | |
| InterlockedDecrement16NoFence() | |
| InterlockedDecrement64() | |
| InterlockedDecrementAcquire64() | |
| InterlockedDecrementRelease64() | |
| InterlockedDecrementNoFence64() | |
| _InterlockedDecrement() | |
| _InterlockedDecrement_acq() | |
| _InterlockedDecrement_rel() | |
| _InterlockedDecrement16() | |
| _InterlockedDecrement16_acq() | |
| _InterlockedDecrement16_rel() | |
| _InterlockedDecrement64() | |
| _InterlockedDecrement64_acq() | |
| _InterlockedDecrement64_rel() | |
| InterlockedExchange() | |
| InterlockedExchangeAcquire( | |
| InterlockedExchangeNoFence() | |
| InterlockedExchange8() | |
| InterlockedExchange16() | |
| InterlockedExchange16Acquire() | |
| InterlockedExchange16NoFence() | |
| InterlockedExchange64() | |
| InterlockedExchangeAcquire64() | |
| InterlockedExchangeNoFence64() | |
| InterlockedExchangePointer() | |
| InterlockedExchangePointerAcquire() | |
| InterlockedExchangePointerNoFence() | |
| InterlockedExchangeAdd() | |
| InterlockedExchangeAddAcquire() | |
| InterlockedExchangeAddRelease() | |
| InterlockedExchangeAddNoFence() | |
| InterlockedExchangeAdd64() | |
| InterlockedExchangeAddAcquire64() | |
| InterlockedExchangeAddRelease64() | |
| InterlockedExchangeAddNoFence64() | |
| InterlockedIncrement() | |
| InterlockedIncrementAcquire() | |
| InterlockedIncrementRelease() | |
| InterlockedIncrementNoFence() | |
| nterlockedIncrement16() | |
| InterlockedIncrement16Acquire() | |
| InterlockedIncrement16Release() | |
| InterlockedIncrement16NoFence() | |
| InterlockedIncrement64() | |
| InterlockedIncrementAcquire64() | |
| InterlockedIncrementRelease64() | |
| InterlockedIncrementNoFence64() | |
| _InterlockedIncrement() | |
| _InterlockedIncrement_acq() | |
| _InterlockedIncrement_rel() | |
| _InterlockedIncrement16() | |
| _InterlockedIncrement16_acq() | |
| _InterlockedIncrement16_rel( | |
| _InterlockedIncrement64() | |
| _InterlockedIncrement64_acq() | |
| _InterlockedIncrement64_rel() | |
If you are authoring a model, it is usually best to have the model call the already-modeled function that is most similar.
If no existing model is appropriate, write your model using the extension functions provided.
For example, suppose we have function myAtomicInc(), and want to make sure that CodeSonar treats it as executing atomically.
int globalCounter;
void myAtomicInc(){ globalCounter++; }
int globalCounter;
void myAtomicInc(){
csonar_mutex_acquire(&csonar_win32_atomic_lock);
globalCounter++;
csonar_mutex_release(&csonar_win32_atomic_lock);
}