Hacker News new | past | comments | ask | show | jobs | submit login

What's the proper fix here?

My knowledge of proper usage of volatile in C is weak. Does it have something to do with the fact that sizeof bool < sizeof int on most platforms?




The trick is to be careful about variable size and alignment and use wrappers around platform-specific load/store operations with the right memory ordering guarantees. There's no portable way to do this in C. But whatever you do, volatile won't be involved.

In that case I mentioned, yes, the issue is that sizeof(bool) = 1 by default on most compilers. You can force it to be 4 on MSVC with a compiler directive but that has its own problems (e.g. you are using a library which uses bools in its API and the library was compiled with sizeof(bool) = 1). The solution is to never use bool, int, etc, directly for variables that will be written to in lock-free code. Use typedefs (or even better for type safety, wrapper structs) that are explicit about size, make all lock-free reads and writes go through library functions/macros that provide the right atomic semantics.

Here's the specific data race with the bools. Assume that sizeof(bool) = 1 and that the two aforementioned bool bytes (call them A and B) wind up next to each other in the same 4-byte aligned word of memory. Thread 1 writes to A and thread 2 writes to B concurrently. It looks like there should be no data race because they're writing to separate variables. But unlike storing a full word to memory, storing a byte involves an implicit read-modify-write, so the only way for this situation to be safe is if thread 1 and 2 use CAS operations to write A and B.


Extremely informative...thanks!


sizeof(_Bool) is probably 1. Whether someone is using stdbool.h or some other bool define (int is common enough) is unassumable. Not all CPUs can do atomic byte operations, so they're going to read/modify/write a machine word at a time.

I'm not sure how much you'd have to mark volatile to get a compiler to behave the way you want, so you could use int and dodge the issue. Or better, the standard sigatomic_t type is provided and should work.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: