Unfortunately, threading operations, locking primitives, and atomic operations were in reasonably wide use long before the various standards committees got around to them. As a result, there is considerable variation in how these operations are supported. It is still quite common to find these operations implemented in assembly language, either for historical reasons or to obtain better performance in specialized circumstances. For example, the gcc __sync_ family of primitives all provide memory-ordering semantics, motivating many developers to create their own implementations for situations where the memory ordering semantics are not required.
Therefore,
Table on
page
provides a rough mapping between the POSIX and
gcc primitives to those used in the Linux kernel.
Exact mappings are not always available, for example, the Linux kernel
has a wide variety of locking primitives, while gcc has a number
of atomic operations that are not directly available in the Linux kernel.
Of course, on the one hand, user-level code does not need the Linux
kernel's wide array of locking primitives, while on the other hand,
gcc's atomic operations can be emulated reasonably straightforwardly
using cmpxchg().
Quick Quiz 5.21: What happened to the Linux-kernel equivalents to fork() and join()? End Quick Quiz
Paul E. McKenney 2011-12-16