...
Code Block | ||||
---|---|---|---|---|
| ||||
struct multi_threaded_flags { unsigned char flag1; unsigned char flag2; }; struct multi_threaded_flags flags; voidint *thread1(void *arg) { flags.flag1 = 1; return 0; } voidint *thread2(void *arg) { flags.flag2 = 2; return 0; } |
...
The same code is compliant when run on a C11-compliant platform. Unlike C99, C11 explicitly defines a memory location and provides the following note, in clause subclause 3.14.2 [ISO/IEC 9899:2011]:
...
Code Block | ||||
---|---|---|---|---|
| ||||
struct multi_threaded_flags { unsigned int flag1 : 2; unsigned int flag2 : 2; }; struct multi_threaded_flags flags; voidint *thread1(void *arg) { flags.flag1 = 1; return 0; } void*int thread2(void *arg) { flags.flag2 = 2; return 0; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <threads.h> #include <assert.h> struct multi_threaded_flags { unsigned int flag1 : 2; unsigned int flag2 : 2; }; union mtf_protect { struct multi_threaded_flags s; long padding; }; struct mtf_mutex { union mtf_protect u; mtx_t mutex; }; struct mtf_mutex flags; void chk_flags(void) { static_assert(sizeof(long) >= sizeof(struct multi_threaded_flags)); } voidint *thread1(void *arg) { if (thrd_success != mtx_lock(&flags.mutex)) { /* Handle error */ } flags.u.s.flag1 = 1; if (thrd_success != mtx_unlock(&flags.mutex)) { /* Handle error */ } return 0; } voidint *thread2(void *arg) { if (thrd_success != mtx_lock(&flags.mutex)) { /* Handle error */ } flags.u.s.flag2 = 2; if (thrd_success != mtx_unlock(&flags.mutex)) { /* Handle error */ } return 0; } |
...
Bibliography
[ISO/IEC 9899:2011] | Clause Subclause 3.14, "Memory Location" |
...