Subversion Repositories Kolibri OS

Rev

Rev 1967 | 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 <kernel.h>
  14. #include <linux/list.h>
  15. #include <asm/atomic.h>
  16.  
  17. /*
  18.  * Simple, straightforward mutexes with strict semantics:
  19.  *
  20.  * - only one task can hold the mutex at a time
  21.  * - only the owner can unlock the mutex
  22.  * - multiple unlocks are not permitted
  23.  * - recursive locking is not permitted
  24.  * - a mutex object must be initialized via the API
  25.  * - a mutex object must not be initialized via memset or copying
  26.  * - task may not exit with mutex held
  27.  * - memory areas where held locks reside must not be freed
  28.  * - held mutexes must not be reinitialized
  29.  * - mutexes may not be used in hardware or software interrupt
  30.  *   contexts such as tasklets and timers
  31.  *
  32.  * These semantics are fully enforced when DEBUG_MUTEXES is
  33.  * enabled. Furthermore, besides enforcing the above rules, the mutex
  34.  * debugging code also implements a number of additional features
  35.  * that make lock debugging easier and faster:
  36.  *
  37.  * - uses symbolic names of mutexes, whenever they are printed in debug output
  38.  * - point-of-acquire tracking, symbolic lookup of function names
  39.  * - list of all locks held in the system, printout of them
  40.  * - owner tracking
  41.  * - detects self-recursing locks and prints out all relevant info
  42.  * - detects multi-task circular deadlocks and prints out all affected
  43.  *   locks and tasks (and only those tasks)
  44.  */
  45. struct mutex {
  46.         /* 1: unlocked, 0: locked, negative: locked, possible waiters */
  47.     atomic_t            count;
  48.         struct list_head        wait_list;
  49. };
  50.  
  51. /*
  52.  * This is the control structure for tasks blocked on mutex,
  53.  * which resides on the blocked task's kernel stack:
  54.  */
  55. struct mutex_waiter {
  56.         struct list_head        list;
  57.     int                *task;
  58. };
  59.  
  60.  
  61. #define __MUTEX_INITIALIZER(lockname) \
  62.                 { .count = ATOMIC_INIT(1) \
  63.                 , .wait_list = LIST_HEAD_INIT(lockname.wait_list) }
  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. /**
  76.  * mutex_is_locked - is the mutex locked
  77.  * @lock: the mutex to be queried
  78.  *
  79.  * Returns 1 if the mutex is locked, 0 if unlocked.
  80.  */
  81. static inline int mutex_is_locked(struct mutex *lock)
  82. {
  83.         return atomic_read(&lock->count) != 1;
  84. }
  85.  
  86. #endif
  87.