4
int b = 1000;
b -= 20;

Is any of the above an atomic operation? What is an atomic operation in C?

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Registered User
  • 5,173
  • 16
  • 47
  • 73
  • 2
    C has no support for threading let alone atomic operations – David Heffernan Jul 04 '11 at 18:49
  • 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. – Hans Passant Jul 04 '11 at 18:51
  • I'd advice you that you are very careful and read a lot before coding anything that uses concurrent memory access. There are a lot of caveats: caching issues (fixed by using `volatile` variables), atomic reads and writes (see `sig_atomic_t` mentioned below), operation atomicity (see the other answers), other race conditions, deadlocks, etc. Read and be careful, and the more you do without concurrent memory access, the easier your life will be. – Rosh Oxymoron Jul 04 '11 at 20:45
  • 2
    @DavidHeffernan That's just plain wrong. `sig_atomic_t` exists since C89(!). – Jens Jul 09 '13 at 21:04
  • @Jens `sig_atomic_t` exists, but how does it allow you to perform arithmetic on variables in an atomic manner? I took this question to be about threading and not about signal handlers. – David Heffernan Jul 09 '13 at 22:15
  • @DavidHeffernan Where does it say thread in the title or question? It says atomic operation in both. And doing arithmetic could be done with `++` on such a type to set a flag. – Jens Jul 11 '13 at 14:48
  • @Jens Define what you mean by atomic operation then please? And in what situations does it matter whether or not an operation is atomic? The question and title also make no mention of signal handlers. And atomic in the context of signal handlers is not the same as atomic in the context of threads. So if we don't know what atomic means, how can we say anything useful? – David Heffernan Jul 11 '13 at 14:50
  • @DavidHeffernan I'm afraid we'll have to ask the OP if his idea of atomic operations is related to what ISO C has to say about accessing an object of `sig_atomic_t`. – Jens Jul 11 '13 at 14:56
  • for `=` and C++: http://stackoverflow.com/questions/8290768/is-assignment-operator-atomic – Ciro Santilli OurBigBook.com Jun 16 '15 at 21:47

5 Answers5

9

It depends on the implementation. By the standard, nothing is atomic in C. If you need atomic ops you can look at your compiler's builtins.

Jens
  • 69,818
  • 15
  • 125
  • 179
BenjaminB
  • 1,809
  • 3
  • 18
  • 32
4

It is architecture/implementation dependent.

If you want atomic operations, I think sig_atomic_t type is standardized by C99, but not sure.

From the GNU LibC docs:

In practice, you can assume that int and other integer types no longer than int are atomic. You can also assume that pointer types are atomic; that is very convenient. Both of these are true on all of the machines that the GNU C library supports, and on all POSIX systems we know of.

Vinicius Kamakura
  • 7,665
  • 1
  • 29
  • 43
  • 1
    Atomicity with respect to signals is very different from atomicity with respect to threads. – R.. GitHub STOP HELPING ICE Jul 04 '11 at 18:51
  • @R, can you explain? It isn't clear to me why that would be so. – andrewdski Jul 04 '11 at 18:57
  • 1
    @hexa You aren't claiming that `b-=20` is threadsafe are you? – David Heffernan Jul 04 '11 at 19:03
  • @DavidHeffernan not at all. `sig_atomic_t` type guarantees that reads and writes are atomic. ONE read ONE write, not composite operations like the one you mentioned – Vinicius Kamakura Jul 04 '11 at 19:14
  • @hexa It's just that the question specifically asked about `b-=20`. As it currently stands your answer is downvote bait. `sig_atomic_t` has nothing to do with the question asked. – David Heffernan Jul 04 '11 at 19:15
  • 1
    @DavidHeffernan he also asks about `int b = 1000`. – Vinicius Kamakura Jul 04 '11 at 19:16
  • @hexa That's not atomic in C. – David Heffernan Jul 04 '11 at 19:17
  • 1
    @andrewdski: think about implementation. To make something atomic with respect to signals, you have to ensure that a signal isn't taken mid-operation. To make something atomic with respect to threads, you have to ensure that no other thread sees the object mid-operation. Taking a signal (especially if you're only worried about atomicity wrt signals taken by this thread) is not at all the same thing as another thread executing. Now, as it happens GNU implements `sig_atomic_t` using a hardware-atomic type, so you get both at once, but as well as not being Unix, GNU is not C. – Steve Jessop Jul 04 '11 at 23:25
  • 1
    ... and a C implementation *could* legally implement `sig_atomic_t` by disabling signals around all accesses using a secret internal lock or flag, but without using atomic CPU instructions and (presuming the C implementation has threading) without disabling multi-threading during accesses. Unlikely, and probably horribly inefficient, but legal, and hence demonstrates a difference in the definition of atomic wrt signals vs atomic wrt threads. – Steve Jessop Jul 04 '11 at 23:31
  • I want to understand when atmoic operations are used and when mutex,semaphores etc are what is the difference in trio? – Registered User Jul 05 '11 at 03:33
2

This link seems to me to be on the right track in telling us what an atomic operation is in C:

http://odetocode.com/blogs/scott/archive/2006/05/17/atomic-operations.aspx

And it says, "...computer science adopted the term 'atomic operation' to describe an instruction that is indivisible and uninterruptible by other threads of execution."

And by that definition, the first line of code in the original question

int b=1000;
b-=20;

ought to be an atomic operation. The second could be an atomic operation if the CPU's instruction set includes an instruction to subtract directly from memory. The reason I think so is that the first code line would most likely require only one assembly (machine) instruction. And instructions either execute or not. I don't think any machine instruction can be interrupted in the middle.

At that same link, says, "If thread A is writing a 32-bit value to memory as an atomic operation, thread B will never be able to read the memory location and see only the first 16 of 32 bits written out." Seems that any single machine instruction cannot be interrupted in the middle, therefore would automatically be atomic between threads.

Indinfer
  • 915
  • 9
  • 6
1

Incrementing and decrementing a number is not an atomic operation in C. Certain architectures support atomic incrementing and decrementing instructions, but there is no guarantee that the compiler would use them. You can look as an example at Qt reference counting. It uses atomic reference counting, on certain platforms it is implemented with platform-specific assembly code, and on the rest it is using a mutex to lock the counter.

If you're not incrementing or decrementing in a performance-critical part of your code, you'd simply use a mutex while doing it. If you're using it in performance-critical part of your code, you might want to try to rewrite your code in a way that doesn't use shared memory for this operation accessed from multiple places for this operation or use mutexes with higher granularity so that they don't affect the performance, or use assembly to ensure that the operation is atomic.

Rosh Oxymoron
  • 20,355
  • 6
  • 41
  • 43
  • Oxymoron I want to understand when atmoic operations are used and when mutex,semaphores etc are what is the difference in trio? – Registered User Jul 05 '11 at 03:32
-1

Quoting from ISO C89, 7.7 Signal handling <signal.h>

The type defined is sig_atomic_t which is the integral type of an object that can be accessed as an atomic entity, even in the presence of asynchronous interrupts.

Jens
  • 69,818
  • 15
  • 125
  • 179