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.
...