Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is assigning a pointer in C program considered atomic on x86-64

https://www.gnu.org/software/libc/manual/html_node/Atomic-Types.html#Atomic-Types says - In practice, you can assume that int is atomic. You can also assume that pointer types are atomic; that is very convenient. Both of these assumptions are true on all of the machines that the GNU C Library supports and on all POSIX systems we know of.

My question is whether pointer assignment can be considered atomic on x86_64 architecture for a C program compiled with gcc m64 flag. OS is 64bit Linux and CPU is Intel(R) Xeon(R) CPU D-1548. One thread will be setting a pointer and another thread accessing the pointer. There is only one writer thread and one reader thread. Reader should either be getting the previous value of the pointer or the latest value and no garbage value in between.

If it is not considered atomic, please let me know how can I use the gcc atomic builtins or maybe memory barrier like __sync_synchronize to achieve the same without using locks. Interested only in C solution and not C++. Thanks!

like image 812
user138645 Avatar asked Aug 03 '20 16:08

user138645


People also ask

Is assigning a pointer Atomic?

Depending on the compiler and the platform, the pointer assignment may or may not be atomic.

Are pointers Atomic C?

As to whether or not this is guaranteed overall in C/C++, the answer is No. The C standard makes no such guarantees. The only way to guarantee a pointer assignment is atomic is to use a platform specific mechanism to guarantee the atomicity of the assignment.

Are X86 instructions Atomic?

x86 guarantees that aligned loads and stores up to 64 bits are atomic, but not wider accesses.

Is assignment atomic in C?

What is an atomic operation in C? Neither of them are, although it is quite rare for the assignment to not be atomic. You have to document the core and compiler to get a useful answer.

How to assign and initialize a pointer in C?

How to Pointer Assignment and Initialization in C. By Dinesh Thakur. When we declare a pointer, it does not point to any specific variable. We must initialize it to point to the desired variable. This is achieved by assigning the address of that variable to the pointer variable, as shown below. int a = 10; int *pa;

What are pointers in C?

What are Pointers? A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before using it to store any variable address.

How to assign an int variable to a pointer variable?

This is achieved by assigning the address of that variable to the pointer variable, as shown below. In this example, the first line declares an int variable named a and initializes it to 10.

What happens when a pointer is decremented in C?

When a pointer is decremented, it actually decrements by the number equal to the size of the data type for which it is a pointer. If an integer pointer that stores address 1000 is decremented, then it will decrement by 2 ( size of an int) and the new address it will points to 998.


Video Answer


2 Answers

Bear in mind that atomicity alone is not enough for communicating between threads. Nothing prevents the compiler and CPU from reordering previous/subsequent load and store instructions with that "atomic" store. In old days people used volatile to prevent that reordering but that was never intended for use with threads and doesn't provide means to specify less or more restrictive memory order (see "Relationship with volatile" in there).

You should use C11 atomics because they guarantee both atomicity and memory order.

like image 114
Maxim Egorushkin Avatar answered Oct 06 '22 05:10

Maxim Egorushkin


For almost all architectures, pointer load and store are atomic. A once notable exception was 8086/80286 where pointers could be seg:offset; there was an l[des]s instruction which could make an atomic load; but no corresponding atomic store.

The integrity of the pointer is only a small concern; your bigger issue revolves around synchronization: the pointer was at value Y, you set it to X; how will you know when nobody is using the (old) Y value? A somewhat related problem is that you may have stored things at X, which the other thread expects to find. Without synchronization, other might see the new pointer value, however what it points to might not be up to date yet.

like image 3
mevets Avatar answered Oct 06 '22 07:10

mevets