2

So, im programming in C89, and its going well so far except one issue, Im doing multithreaded applications and I need to use atomic.

I dont want to switch to C11 because I want my code to be compatable on every compiler and system and for my code to last a very long time.

Iv'e searched through stackoverflow for an existing question on this topic but didn't find any questions.

Does anyone know how to use the Atomic in C89. Say I have two threads using a bool

#include <stdatomic.h>
_Atomic bool theBool = false;

void funFromThirstThread()
{
    theBool = true;
}

void funFromSecondThread() /*gets called repeatedly*/
{
    if(theBool)
    {
        /*Do something*/
    }
}

The above code is what I would do in C11, using the atomic in that, but how would I do this in C89? Can this be done? Preferably without volatile and locks thanks.

  • 8
    Using platform specific code was the way to do it pre-C11 – UnholySheep Jul 02 '22 at 18:09
  • 3
    Also how do you create threads in a cross-platform way without C11? That should also be using platform specific code – UnholySheep Jul 02 '22 at 18:10
  • 4
    If you can't avoid using C89, you can't avoid using non-standard constructions. There was no standard way in C89 (or in C99, for that matter) to handle atomic operations in C. You will have to use platform-specific constructs. Actually, most C89 compilers simply won't have a way to achieve atomics — you'll have to drop into assembler. It would be far more sensible to upgrade to a version of the standard with support for atomic types and operations. – Jonathan Leffler Jul 02 '22 at 18:11
  • @UnholySheep using plibsys external libary –  Jul 02 '22 at 18:11
  • 7
    plibsys has atomic operations support: https://saprykin.github.io/plibsys-docs/patomic_8h.html - so you should use that as well for consistency? – UnholySheep Jul 02 '22 at 18:13
  • Do you need any memory ordering? If not, `volatile bool` generally works similarly to `memory_order_relaxed`. [When to use volatile with multi threading?](https://stackoverflow.com/a/58535118) – Peter Cordes Jul 02 '22 at 20:46

1 Answers1

4

It can't be done.

Prior to C11, to get atomic operations, you had to use inline assembler or compiler-specific intrinsics to access the appropriate instructions. And since the language had no formal memory model, you had to rely on knowledge of compiler-specific internals (often undocumented) to know what optimizations it would or wouldn't perform in what contexts. Or else, throw around a lot of volatiles and cross your fingers. Sometimes both. Nothing was portable in any way, and subtle bugs were common.

If there had been a reliable and portable way to use atomics prior to C11, then C11 probably wouldn't have bothered to include them. There is a very good reason why they did.

Per the comments, you say you are using the plibsys library for threads, and UnholySheep points out that it also has support for atomics. So you should probably just use those. Still, though, keep in mind that a generic C89 compiler doesn't make any promises to avoid optimizations that would break the required memory ordering. Usually they were not smart enough to do such optimizations in the first place, but everything is much more at your own risk.

I dont want to switch to C11 because I want my code to be compatible on every compiler and system and for my code to last a very long time.

That goal is basically unattainable for any program more complex than "Hello World". But my feeling is that using C11 gets you closer to it, not further away.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82