...
Code Block | ||||
---|---|---|---|---|
| ||||
struct multi_threaded_flags { unsigned char flag1; unsigned char flag2; }; struct multi_threaded_flags flags; void* thread1(void*) { flags.flag1 = 1; return 0; } void* thread2(void*) { flags.flag2 = 2; return 0; } |
Although this code appears to be harmless, it is possible that flag1
and flag2
are stored in the same word. If both assignments occur on a thread-scheduling interleaving that ends with both stores occurring after one another, it is possible that only one of the flags will be set as intended, and the other flag will equal its previous value, because both chars are represented by the same word, which is the smallest unit the processor can work on. C99 makes no guarantees that these flags can be modified concurrently.
...
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; return 0; } void* thread2(void*) { flags.flag2 = 2; return 0; } |
The C Standard, Section 3.14.3 [ISO/IEC 9899:2011], states:
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <threads.h> struct multi_threaded_flags { unsigned int flag1 : 2; 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; mtx_t mutex; }; struct mtf_mutex flags; void* thread1(void*) { int result; if ((result = mtx_lock(&flags.mutex)) == thrd_error) { /* Handle error */ } flags.u.s.flag1 = 1; if ((result = mtx_unlock(&flags.mutex)) == thrd_error) { /* Handle error */ } return 0; } void* thread2(void*) { int result; if ((result = mtx_lock(&flags.mutex)) == thrd_error) { /* Handle error */ } flags.u.s.flag2 = 2; if ((result = mtx_unlock(&flags.mutex)) == thrd_error) { /* Handle error */ } return 0; } |
Static assertions are discussed in detail in DCL03-C. Use a static assertion to test the value of a constant expression.
...