Safe loading / storage of 64-bit operations with 32-bit instances

In Redis, I use the atomicvar.h header file , which implements thread-safe atomic operations on integers using different means depending on the compiler (and version). There are currently three different implementations based on:

  • __ sync synchronizers like __sync_add_and_fetch etc.
  • __ atomic built-in functions like __atomic_add_fetch
  • puteread mutexes if none of the above are available

However, since Redis moves more into threads, I need to do more than this header provides. For example, I need to safely store a 64-bit value (even if Redis is compiled with -m32

a 32-bit target).

While __atomic provides load / store operations, __sync does not seem to have this, even though it does more complex operations like fetch and /, fetch and add, etc., apparently does not trivial fetch_and_store.

The best I've found so far is to use the following to implement secure 64-bit storage:

while(!__sync_bool_compare_and_swap(&var,var,new_value));

      

This is clearly overkill, since I do not want a check-and-set operation, I just want to write the value in such a way that I am sure that other threads will not read the "half value", for example, the first 32 bits of the previous value and the next 32 bits new meaning.

Am I missing something, or is the above really the best solution?

Currently I cannot use C11 _Atomic, at least for 4.0 (but I will be switching in the future) because still very popular Linux distributions have GCC versions that do not support C11.

For reading, I am currently using:

__sync_add_and_fetch(&var,0);

      

While not ideal (useless zero addition), at least it doesn't require a loop.

+3


source to share





All Articles