William Breathitt Gray
William Breathitt Gray

Reputation: 11966

Purpose of the ATOMIC_INIT macro in the Linux kernel

I'm reading the Linux Device Drivers 3rd Edition book online and I'm having trouble understanding the initialization macro for atomic variables:

static atomic_t foobar = ATOMIC_INIT(1);

I've looked through the source code for the Linux kernel v3.2, but I've only come up with two definitions:

#define ATOMIC_INIT(i) { (i) }

and

#define ATOMIC_INIT(i) ((atomic_t) { (i) })

The second version of the definition for the macro seems to be functionally the same as the first -- in fact, it seems redundant to even have an explicit cast when the value would be implicitly cast anyway to atomic_t. Why are there two versions of the definition?

Is the purpose of the ATOMIC_INIT macro just to keep code from breaking if the atomic_t structure changes in a future release of the Linux kernel?

Upvotes: 5

Views: 8143

Answers (2)

Jens Gustedt
Jens Gustedt

Reputation: 78903

The difference between the two different forms of ATOMIC_INIT is that the first can only be used in initializations, the second can be used in initializations and assignments. At a first glance this sounds as if the second would be preferable, but it has an important use case where it can't be applied: block scope variables that are declared with static storage specification. In block scope

static atomic_t foobar = ((atomic_t) { (1) });

would be invalid for standard C, because the initializer would not be a compile time constant expression. (In file scope the compound literal would be statically allocated so it would work, there.)

I remember vaguely a discussion on the kernel list that mentioned that gcc has an extension that allows such code, and that this is one of the reasons they don't move on to C99 but stick to gnu89 as a C dialect.

Upvotes: 2

CL.
CL.

Reputation: 180020

Many atomic operations must be implemented separately for each architecture. The purpose of the various macros and functions in atomic.h is to hide the differences between architectures.

In practice, all architectures use a single 32-bit variable to implement atomic_t, so there is no practical difference in the various ATOMIC_INIT macros; all the interesting stuff happens in the operations. But the internals might change (and did change once for 32-bit SPARC), so you always should use the offical API.

Upvotes: 4

Related Questions