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

Paul E. McKenney 2011-12-16