5.4 Linux-Kernel Equivalents to POSIX Operations
Keywords: perfbook_html

#
5.4 Linux-Kernel Equivalents to POSIX Operations

Table: Mapping from POSIX to Linux-Kernel Primitives
Category | POSIX | Linux Kernel
Thread Management | pthread_t | struct task_struct
| pthread_create() | kthread_create
| pthread_exit() | kthread_should_stop() (rough)
| pthread_join() | kthread_stop() (rough)
| poll(NULL, 0, 5) | schedule_timeout_interruptible()
POSIX Locking | pthread_mutex_t | spinlock_t (rough)
|  | struct mutex
| PTHREAD_MUTEX_INITIALIZER | DEFINE_SPINLOCK()
|  | DEFINE_MUTEX()
| pthread_mutex_lock() | spin_lock() (and friends)
|  | mutex_lock() (and friends)
| pthread_mutex_unlock() | spin_unlock() (and friends)
|  | mutex_unlock()
POSIX Reader-Writer | pthread_rwlock_t | rwlock_t (rough)
Locking |  | struct rw_semaphore
| PTHREAD_RWLOCK_INITIALIZER | DEFINE_RWLOCK()
|  | DECLARE_RWSEM()
| pthread_rwlock_rdlock() | read_lock() (and friends)
|  | down_read() (and friends)
| pthread_rwlock_unlock() | read_unlock() (and friends)
|  | up_read()
| thread_rwlock_wrlock() | write_lock() (and friends)
|  | down_write() (and friends)
| pthread_rwlock_unlock() | write_unlock() (and friends)
|  | up_write()
Atomic Operations | C Scalar Types | atomic_t
|  | atomic64_t
| __sync_fetch_and_add() | atomic_add_return()
|  | atomic64_add_return()
| __sync_fetch_and_sub() | atomic_sub_return()
|  | atomic64_sub_return()
| __sync_val_compare_and_swap() | cmpxchg()
| __sync_lock_test_and_set() | xchg() (rough)
| __sync_synchronize() | smp_mb()

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