diff options
| author | Matthew Wilcox <matthew@wil.cx> | 2008-04-11 15:23:52 -0400 | 
|---|---|---|
| committer | Matthew Wilcox <willy@linux.intel.com> | 2008-04-17 10:43:01 -0400 | 
| commit | 714493cd5468f42ca3c4f730a9c17c203abd5059 (patch) | |
| tree | 9d087ad3b74cb1bd6fbd9be486fc2b361c6407dd /kernel/semaphore.c | |
| parent | b17170b2fac96705db3188f093f89e8e838418e4 (diff) | |
| download | olio-linux-3.10-714493cd5468f42ca3c4f730a9c17c203abd5059.tar.xz olio-linux-3.10-714493cd5468f42ca3c4f730a9c17c203abd5059.zip  | |
Improve semaphore documentation
Move documentation from semaphore.h to semaphore.c as requested by
Andrew Morton.  Also reformat to kernel-doc style and add some more
notes about the implementation.
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
Diffstat (limited to 'kernel/semaphore.c')
| -rw-r--r-- | kernel/semaphore.c | 79 | 
1 files changed, 68 insertions, 11 deletions
diff --git a/kernel/semaphore.c b/kernel/semaphore.c index bef977b1696..5c2942e768c 100644 --- a/kernel/semaphore.c +++ b/kernel/semaphore.c @@ -3,6 +3,26 @@   * Author: Matthew Wilcox <willy@linux.intel.com>   *   * Distributed under the terms of the GNU GPL, version 2 + * + * This file implements counting semaphores. + * A counting semaphore may be acquired 'n' times before sleeping. + * See mutex.c for single-acquisition sleeping locks which enforce + * rules which allow code to be debugged more easily. + */ + +/* + * Some notes on the implementation: + * + * The spinlock controls access to the other members of the semaphore. + * down_trylock() and up() can be called from interrupt context, so we + * have to disable interrupts when taking the lock.  It turns out various + * parts of the kernel expect to be able to use down() on a semaphore in + * interrupt context when they know it will succeed, so we have to use + * irqsave variants for down(), down_interruptible() and down_killable() + * too. + * + * The ->count variable represents how many more tasks can acquire this + * semaphore.  If it's zero, there may be tasks waiting on the wait_list.   */  #include <linux/compiler.h> @@ -12,22 +32,23 @@  #include <linux/semaphore.h>  #include <linux/spinlock.h> -/* - * Some notes on the implementation: - * - * down_trylock() and up() can be called from interrupt context. - * So we have to disable interrupts when taking the lock. - * - * The ->count variable defines how many more tasks can acquire the - * semaphore.  If it's zero, there may be tasks waiting on the list. - */ -  static noinline void __down(struct semaphore *sem);  static noinline int __down_interruptible(struct semaphore *sem);  static noinline int __down_killable(struct semaphore *sem);  static noinline int __down_timeout(struct semaphore *sem, long jiffies);  static noinline void __up(struct semaphore *sem); +/** + * down - acquire the semaphore + * @sem: the semaphore to be acquired + * + * Acquires the semaphore.  If no more tasks are allowed to acquire the + * semaphore, calling this function will put the task to sleep until the + * semaphore is released. + * + * Use of this function is deprecated, please use down_interruptible() or + * down_killable() instead. + */  void down(struct semaphore *sem)  {  	unsigned long flags; @@ -41,6 +62,15 @@ void down(struct semaphore *sem)  }  EXPORT_SYMBOL(down); +/** + * down_interruptible - acquire the semaphore unless interrupted + * @sem: the semaphore to be acquired + * + * Attempts to acquire the semaphore.  If no more tasks are allowed to + * acquire the semaphore, calling this function will put the task to sleep. + * If the sleep is interrupted by a signal, this function will return -EINTR. + * If the semaphore is successfully acquired, this function returns 0. + */  int down_interruptible(struct semaphore *sem)  {  	unsigned long flags; @@ -57,6 +87,16 @@ int down_interruptible(struct semaphore *sem)  }  EXPORT_SYMBOL(down_interruptible); +/** + * down_killable - acquire the semaphore unless killed + * @sem: the semaphore to be acquired + * + * Attempts to acquire the semaphore.  If no more tasks are allowed to + * acquire the semaphore, calling this function will put the task to sleep. + * If the sleep is interrupted by a fatal signal, this function will return + * -EINTR.  If the semaphore is successfully acquired, this function returns + * 0. + */  int down_killable(struct semaphore *sem)  {  	unsigned long flags; @@ -78,7 +118,7 @@ EXPORT_SYMBOL(down_killable);   * @sem: the semaphore to be acquired   *   * Try to acquire the semaphore atomically.  Returns 0 if the mutex has - * been acquired successfully and 1 if it is contended. + * been acquired successfully or 1 if it it cannot be acquired.   *   * NOTE: This return value is inverted from both spin_trylock and   * mutex_trylock!  Be careful about this when converting code. @@ -101,6 +141,16 @@ int down_trylock(struct semaphore *sem)  }  EXPORT_SYMBOL(down_trylock); +/** + * down_timeout - acquire the semaphore within a specified time + * @sem: the semaphore to be acquired + * @jiffies: how long to wait before failing + * + * Attempts to acquire the semaphore.  If no more tasks are allowed to + * acquire the semaphore, calling this function will put the task to sleep. + * If the semaphore is not released within the specified number of jiffies, + * this function returns -ETIME.  It returns 0 if the semaphore was acquired. + */  int down_timeout(struct semaphore *sem, long jiffies)  {  	unsigned long flags; @@ -117,6 +167,13 @@ int down_timeout(struct semaphore *sem, long jiffies)  }  EXPORT_SYMBOL(down_timeout); +/** + * up - release the semaphore + * @sem: the semaphore to release + * + * Release the semaphore.  Unlike mutexes, up() may be called from any + * context and even by tasks which have never called down(). + */  void up(struct semaphore *sem)  {  	unsigned long flags;  |