Reader-writer semaphores

This interface is an implementation of sleeping reader-writer exclusion, which serves as an alternative for spinning ones. Reader-writer semaphores are represented by struct rw_semaphore, declared in the kernel header <linux/rwsem.h>:

struct rw_semaphore {
        atomic_long_t count;
        struct list_head wait_list;
        raw_spinlock_t wait_lock;
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
       struct optimistic_spin_queue osq; /* spinner MCS lock */
       /*
       * Write owner. Used as a speculative check to see
       * if the owner is running on the cpu.
       */
      struct task_struct *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
     struct lockdep_map dep_map;
#endif
};

This structure is identical to that of a mutex, and is designed to support optimistic spinning with osq; it also includes debug support through the kernel's lockdep. Count serves as an exclusion counter, which is set to 1, allowing a maximum of one writer to own the lock at a point in time. This works since mutual exclusion is only enforced between contending writers, and any number of readers can concurrently share the read lock. wait_lock is a spinlock which protects the semaphore wait_list.

An rw_semaphore can be instantiated and initialized statically through DECLARE_RWSEM(name), and alternatively, it can be dynamically initialized through init_rwsem(sem).

As with the case of rw-spinlocks, this interface too offers distinct routines for lock acquisition in reader and writer paths. Following is a list of interface operations:

/* reader interfaces */
void down_read(struct rw_semaphore *sem);
void up_read(struct rw_semaphore *sem); /* trylock for reading -- returns 1 if successful, 0 if contention */ int down_read_trylock(struct rw_semaphore *sem);
void up_read(struct rw_semaphore *sem);

/* writer Interfaces */
void down_write(struct rw_semaphore *sem);
int __must_check down_write_killable(struct rw_semaphore *sem);

/* trylock for writing -- returns 1 if successful, 0 if contention */
int down_write_trylock(struct rw_semaphore *sem);
void up_write(struct rw_semaphore *sem); /* downgrade write lock to read lock */
void downgrade_write(struct rw_semaphore *sem);

/* check if rw-sem is currently locked */
int rwsem_is_locked(struct rw_semaphore *sem);

These operations are implemented in the source file <kernel/locking/rwsem.c>; the code is quite self explanatory and we will not discuss it any further.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.186.201