synchronization

Causes of Concurrency in Userland

Causes of Concurrency in Kernel

xxx-safe

Whenever you write kernel code, you should ask yourself these questions:

lock contention

The term lock contention, or simply contention, describes a lock currently in use but that another thread is trying to acquire.A lock that is highly contended often has threads waiting to acquire it. High contention can occur because a lock is frequently obtained, held for a long time after it is obtained, or both.

Atomic operations

typedef struct { int counter; } atomic_t;

Atomic Integer Operation Description
ATOMIC_INIT(int i) At declaration, initialize to i.
int atomic_read(atomic_t *v) Atomically read the integer value of v.
void atomic_set(atomic_t *v, int i) Atomically set v equal to i.
void atomic_add(int i, atomic_t *v) Atomically add i to v.
void atomic_sub(int i, atomic_t *v) Atomically subtract i from v.
void atomic_inc(atomic_t *v) Atomically add one to v.
void atomic_dec(atomic_t *v) Atomically subtract one from v.
int atomic_sub_and_test(int i, atomic_t *v) Atomically subtract i from v and return true if the result is zero; otherwise false.
int atomic_add_negative(int i, atomic_t *v) Atomically add i to v and return true if the result is negative; otherwise false.
int atomic_add_return(int i, atomic_t *v) Atomically add i to v and return the result.
int atomic_sub_return(int i, atomic_t *v) Atomically subtract i from v and return the result.
int atomic_inc_return(int i, atomic_t *v) Atomically increment v by one and return the result.
int atomic_dec_return(int i, atomic_t *v) Atomically decrement v by one and return the result.
int atomic_dec_and_test(atomic_t *v) Atomically decrement v by one and return true if zero; false otherwise.
int atomic_inc_and_test(atomic_t *v) Atomically increment v by one and return true if the result is zero; false otherwise.

Atomic and Ordering

64-Bit Atomic Operations

typedef struct { long counter; } atomic64_t;

Same as atomic integer, only operations on 64-bit and return long as its value. All operations have atomic64_ prefix.

Atomic Bitwise Operations

All bitwise operations are in <asm/bitops.h>

The bitop functions are defined to work on unsigned longs: - x64 system the bits numbered: + |0…………..63|64…………127|128………..191|192………..255| - ppc64 system the bits numbered: + |63…………..0|127…………64|191………..128|255………..192| - and on ppc32: + |31…..0|63….32|95….64|127…96|159..128|191..160|223..192|255..224|

Atomic Bitwise Operation Description
void set_bit(int nr, void *addr) Atomically set the nr -th bit starting from addr.
void clear_bit(int nr, void *addr) Atomically clear the nr -th bit starting from addr.
void change_bit(int nr, void *addr) Atomically flip the value of the nr -th bit starting from addr.
int test_and_set_bit(int nr, void *addr) Atomically set the nr -th bit starting from addr and return the previous value.
int test_and_clear_bit(int nr, void *addr) Atomically clear the nr -th bit starting from addr and return the previous value.
int test_and_change_bit(int nr, void *addr) Atomically flip the nr -th bit starting from addr and return the previous value.
int test_bit(int nr, void *addr) Atomically return the value of the nr - th bit starting from addr.

nr is the bit number, and there are no limitations on the bit number supplied i. e. nr can be greater than word-size on the architecture, but usually we do not use nr greater than word-size.

Atomic bitwise operations and their nonatomic versions are the only way for platform independent bitmap.

Locks

Spin Lock

  1. disable preemption
  2. acquire lock (try lock and spin) ### spin_unlock
  3. release lock
  4. enable preemption ### spin_lock_irq
  5. disable local interrupt
  6. disable preemption
  7. acquire lock (try lock and spin) ### spin_unlock_irq
  8. release lock
  9. enable local interrupt
  10. enable preemption ### spin_lock_irqsave
  11. disable local interrupt and save the interrupt flag
  12. disable preemption
  13. acquire lock (try lock and spin) ### spin_unlock_irqrestore
  14. release lock
  15. enable local interrupt and restore the interrupt flag
  16. enable preemption
comments powered by Disqus