Subversion Repositories Kolibri OS

Rev

Rev 2161 | Rev 5056 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Mutexes: blocking mutual exclusion locks
  3.  *
  4.  * started by Ingo Molnar:
  5.  *
  6.  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
  7.  *
  8.  * This file contains the main data structure and API definitions.
  9.  */
  10. #ifndef __LINUX_MUTEX_H
  11. #define __LINUX_MUTEX_H
  12.  
  13. #include <linux/list.h>
  14. #include <asm/atomic.h>
  15.  
  16. /*
  17.  * Simple, straightforward mutexes with strict semantics:
  18.  *
  19.  * - only one task can hold the mutex at a time
  20.  * - only the owner can unlock the mutex
  21.  * - multiple unlocks are not permitted
  22.  * - recursive locking is not permitted
  23.  * - a mutex object must be initialized via the API
  24.  * - a mutex object must not be initialized via memset or copying
  25.  * - task may not exit with mutex held
  26.  * - memory areas where held locks reside must not be freed
  27.  * - held mutexes must not be reinitialized
  28.  * - mutexes may not be used in hardware or software interrupt
  29.  *   contexts such as tasklets and timers
  30.  *
  31.  * These semantics are fully enforced when DEBUG_MUTEXES is
  32.  * enabled. Furthermore, besides enforcing the above rules, the mutex
  33.  * debugging code also implements a number of additional features
  34.  * that make lock debugging easier and faster:
  35.  *
  36.  * - uses symbolic names of mutexes, whenever they are printed in debug output
  37.  * - point-of-acquire tracking, symbolic lookup of function names
  38.  * - list of all locks held in the system, printout of them
  39.  * - owner tracking
  40.  * - detects self-recursing locks and prints out all relevant info
  41.  * - detects multi-task circular deadlocks and prints out all affected
  42.  *   locks and tasks (and only those tasks)
  43.  */
  44. struct mutex {
  45.         /* 1: unlocked, 0: locked, negative: locked, possible waiters */
  46.         struct list_head        wait_list;
  47.     atomic_t            count;
  48. };
  49.  
  50. /*
  51.  * This is the control structure for tasks blocked on mutex,
  52.  * which resides on the blocked task's kernel stack:
  53.  */
  54. struct mutex_waiter {
  55.         struct list_head        list;
  56.     int                *task;
  57. };
  58.  
  59.  
  60. #define __MUTEX_INITIALIZER(lockname) \
  61.                 { .wait_list = LIST_HEAD_INIT(lockname.wait_list), \
  62.                   .count = ATOMIC_INIT(1) \
  63.                 }
  64.  
  65. #define DEFINE_MUTEX(mutexname) \
  66.         struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
  67.  
  68. void __attribute__ ((fastcall)) __attribute__ ((dllimport))
  69.      mutex_init(struct mutex*)__asm__("MutexInit");
  70. void __attribute__ ((fastcall)) __attribute__ ((dllimport))
  71.      mutex_lock(struct mutex*)__asm__("MutexLock");
  72. void __attribute__ ((fastcall)) __attribute__ ((dllimport))
  73.      mutex_unlock(struct mutex*)__asm__("MutexUnlock");
  74.  
  75. static inline int mutex_lock_interruptible(struct mutex *lock)
  76. {
  77.     mutex_lock(lock);
  78.     return 0;
  79. }
  80.  
  81. # define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock)
  82.  
  83.  
  84. /**
  85.  * mutex_is_locked - is the mutex locked
  86.  * @lock: the mutex to be queried
  87.  *
  88.  * Returns 1 if the mutex is locked, 0 if unlocked.
  89.  */
  90. static inline int mutex_is_locked(struct mutex *lock)
  91. {
  92.         return atomic_read(&lock->count) != 1;
  93. }
  94.  
  95. #endif
  96.