On the guarantee of atomicity in C

On x86 computers, instructions such as inc, addl are not atomic and in an SMP environment it is not safe to use them without the lock prefix. But in UP environment it is safe, as inc, addl and other simple instructions will not be interrupted.

My problem is, given a C level instruction like

x = x + 1;

      

Is there any guarantee that the C compiler will always use UP safe instructions such as

incl %eax

      

but aren't these unsafe instructions (for example, implementing a C instruction in multiple instructions that can be interrupted by the context switch) even in a UP environment?

+2


source to share


8 answers


There is absolutely no guarantee that it "x - x + 1"

will compile for instructions with interrupts on any platform, including x86. It is possible that it is safe for a particular compiler and a particular processor architecture, but it is not stipulated in the standards at all, and the standard is the only guarantee you get.

You cannot assume anything is safe based on what you think will compile. Even if a particular compiler / architecture claims to be there, relying on it is very bad since it reduces portability. Other compilers, architectures, or even later versions in the same compiler and architecture can break your code easily.

It is highly possible that it x = x + 1

can compile an arbitrary sequence such as:

load r0,[x]  ; load memory into reg 0
incr r0      ; increment reg 0
stor [x],r0  ; store reg 0 back to memory

      

on a processor that has no instructions for expanding memory. Or it might be smart and compile it to:



lock         ; disable task switching (interrupts)
load r0,[x]  ; load memory into reg 0
incr r0      ; increment reg 0
stor [x],r0  ; store reg 0 back to memory
unlock       ; enable task switching (interrupts)

      

where is lock

disabled, and unlock

- interrupts. But even then, it might not be safe on an architecture with more than one of these CPUs sharing memory ( lock

can only disable interrupts for one CPU), as you said.

The language itself (or libraries for it if it is not built into the language) will provide thread-safe constructs, and you should use them rather than rely on your understanding (or perhaps not understanding) of what machine code will be generated.

Things like Java synchronized

and pthread_mutex_lock()

(available for C under some OS) are what you want to learn.

+4


source


Not.

You can use "volatile", which prevents the compiler from holding x in a temporary register, and for most purposes this will actually have the intended effect. But this is not guaranteed.



To be on the safe side, you should either use the inline asm, or if you need to be portable, encapsulate the increment with mutexes.

+6


source


If you are using GLib, they have macros for atomic int and pointer operations.

http://library.gnome.org/devel/glib/stable/glib-Atomic-Operations.html

+4


source


Recent versions of GCC have built-in __sync_xxx functions to do exactly what you want.

Instead of writing:

x + = 1;

write this:

__ sync_fetch_and_add (& x, 1);

And gcc will make sure it compiles to atomic opcode. This is now supported on the most important arches.

http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html

This stems from Intel's recommendations for C on ia64, but has now found ways to use gcc for many other arcs. Therefore, it is even slightly portable.

+4


source


Is there any guarantee that the C compiler will always use UP safe instructions

Not in the C standard. But your compiler / standard library may provide you with special types or certain guarantees.

This gcc doc may be as per what you need.

+1


source


I believe you need to resort to the SMP addresses of the libraries or use your own inline assembly code.

0


source


A C compiler can implement a type statement x = x + 1

in multiple statements.
You can use the register keyword to hint that the compiler is using register instead of memory, but the compiler may ignore it.

I suggest using OS-specific locks such as the In-App Lock Function in Windows.

0


source


Worrying about x86 only is horribly unsporting coding. This is one of those seemingly small coding tasks that is a project in itself. Find an existing library project that solves this problem for a wide range of platforms and uses it. GLib seems to be one of what the Kaiser .se says.

0


source







All Articles