Is there a way to make a function atomic in C?

13,289

Solution 1

Maybe.

It depends entirely on your definition of "atomic".

  • In a single core, deeply embedded environment without an operating system involved you can usually disable and enable interrupts. This can be used to allow a function to be atomic against interrupt handler code. But if you have a multi-master bus, a DMA engine, or some other hardware device that can write memory independently, then even masking interrupts might not provide a strong enough guarantee in some circumstances.

  • In an RTOS (real time operating system) environment, the OS kernel usually provides low level synchronization primitives such as critical sections. A critical section is a block of code that behaves "essentially" atomically, at least with respect to all other critical sections. It is usually fundamental to the OS's implementation of other synchronization primitives.

  • In a multi-core environment, a low level primitive called a spinlock is often available. It is used to guard against entry to a block of code that must be atomic with respect to other users of the same spinlock object, and operates by blocking the waiting CPU core in a tight loop until the lock is released (hence the name).

  • In many threading environments, more complex primitives such as events, semaphores, mutexes, and queues are provided by the threading framework. These cooperate with the thread scheduler such that threads waiting for something to happen don't run at all until the condition is met. These can be used to make a function's actions atomic with respect to other threads sharing the same synchronization object.

A general rule would be to use the highest level capabilities available in your environment that are suited to the task. In the best case, an existing thread safe object such as a message queue can be used to avoid needing to do anything special in your code at all.

Solution 2

If you want to make sure your function won't be interrupted by signal, use sigprocmask() to mask and unmask signals, although some signals cannot be blocked (like SIGKILL) and behaviour for blocking some signals (like SIGSEGV) is undefined.

See man sigprocmask for details.

Solution 3

If by atomic you mean 'only one thread at a time', then you could just protect the function with a Critical Section block (in Windows). In Linux, I use a mutex lock/unlock to more or less emulate a critical section.

Solution 4

Not portably, at least. For some systems, you can probably approach it, by doing things like turning of machine interrupts, to prevent the kernel from pre-empting your function. But it will be very hard, especially for non-embedded systems.

Solution 5

You'll need platform-specific support to do that - either through use of special compiler intrinsics for hardware instructions, or by using operating system support. Neither C nor C++ has standardized synchronization stuff.

Share:
13,289
FL4SOF
Author by

FL4SOF

Updated on July 29, 2022

Comments

  • FL4SOF
    FL4SOF almost 2 years

    Is there a way to make a function atomic in C.

    I am not looking for a portable solution.(platforms looking for - Win,Linux)