When multiple threads must access or make modifications to a common variable, they may also inadvertently access other variables adjacent in memory. This is an artifact of variables being stored compactly, with one byte possibly holding multiple variables, and is a common optimization on word-addressed machines. Bit-fields are especially prone to this behavior , since C is designed because compliers are allowed to store multiple bit-fields in one addressable byte or word. This implies that race conditions may exist not just on a variable accessed by multiple threads, but also on other variables sharing the same byte or word address.
A common tool for preventing race conditions in concurrent programming is the mutex. When properly observed by all threads, a mutex may can provide safe and secure access to a common variable, however, it guarantees nothing regarding other variables that might be accessed when a common variable is accessed.
Unfortunately there is no portable way to determine just what which adjacent variables are may be stored along with a certain variable.
...
Noncompliant Code Example (Bit Field)
In the following this noncompliant code example, two executing threads simultaneously access two separate members of a global struct.
| Code Block | ||
|---|---|---|
| ||
struct multi_threaded_flags {
unsigned int flag1 : 2;
unsigned int flag2 : 2;
};
struct multi_threaded_flags flags;
void thread1(void) {
flags.flag1 = 1;
}
void thread2(void) {
flags.flag2 = 2;
}
|
...
| Code Block | ||
|---|---|---|
| ||
struct multi_threaded_flags {
volatile unsigned int flag1 : 2;
volatile unsigned int flag2 : 2;
};
union mtf_protect {
struct multi_threaded_flags s;
long padding;
};
static_assert(sizeof( long) >= sizeof( struct multi_threaded_flags));
struct mtf_mutex {
union mtf_protect u;
pthread_mutex_t mutex;
};
struct mtf_mutex flags;
void thread1(void) {
pthread_mutex_lock(&flags.mutex);
flags.u.s.flag1 = 1;
pthread_mutex_unlock(&flags.mutex);
}
void thread2(void) {
pthread_mutex_lock(&flags.mutex);
flags.u.s.flag2 = 2;
pthread_mutex_unlock(&flags.mutex);
}
|
Static assertions are discussed more thoroughly in detail in DCL03-C. Use a static assertion to test the value of a constant expression.
...
Although the race window is narrow, having an assignment or an expression evaluate improperly due to because of misinterpreted data can possibly result in a corrupted running state or unintended information disclosure.
...