Rev 6082 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1616 | serge | 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 |
||
7 | * |
||
8 | * This file contains the main data structure and API definitions. |
||
9 | */ |
||
10 | #ifndef __LINUX_MUTEX_H |
||
11 | #define __LINUX_MUTEX_H |
||
12 | |||
5270 | serge | 13 | #include |
1616 | serge | 14 | #include |
5272 | serge | 15 | #include |
5270 | serge | 16 | #include |
17 | #include |
||
5272 | serge | 18 | #include |
5270 | serge | 19 | #include |
1616 | serge | 20 | |
21 | /* |
||
22 | * Simple, straightforward mutexes with strict semantics: |
||
23 | * |
||
24 | * - only one task can hold the mutex at a time |
||
25 | * - only the owner can unlock the mutex |
||
26 | * - multiple unlocks are not permitted |
||
27 | * - recursive locking is not permitted |
||
28 | * - a mutex object must be initialized via the API |
||
29 | * - a mutex object must not be initialized via memset or copying |
||
30 | * - task may not exit with mutex held |
||
31 | * - memory areas where held locks reside must not be freed |
||
32 | * - held mutexes must not be reinitialized |
||
33 | * - mutexes may not be used in hardware or software interrupt |
||
34 | * contexts such as tasklets and timers |
||
35 | * |
||
36 | * These semantics are fully enforced when DEBUG_MUTEXES is |
||
37 | * enabled. Furthermore, besides enforcing the above rules, the mutex |
||
38 | * debugging code also implements a number of additional features |
||
39 | * that make lock debugging easier and faster: |
||
40 | * |
||
41 | * - uses symbolic names of mutexes, whenever they are printed in debug output |
||
42 | * - point-of-acquire tracking, symbolic lookup of function names |
||
43 | * - list of all locks held in the system, printout of them |
||
44 | * - owner tracking |
||
45 | * - detects self-recursing locks and prints out all relevant info |
||
46 | * - detects multi-task circular deadlocks and prints out all affected |
||
47 | * locks and tasks (and only those tasks) |
||
48 | */ |
||
49 | struct mutex { |
||
50 | /* 1: unlocked, 0: locked, negative: locked, possible waiters */ |
||
51 | struct list_head wait_list; |
||
6082 | serge | 52 | atomic_t count; |
1616 | serge | 53 | }; |
54 | |||
55 | /* |
||
56 | * This is the control structure for tasks blocked on mutex, |
||
57 | * which resides on the blocked task's kernel stack: |
||
58 | */ |
||
59 | struct mutex_waiter { |
||
60 | struct list_head list; |
||
9833 | turbocat | 61 | void *task; |
1616 | serge | 62 | }; |
63 | |||
1967 | serge | 64 | |
65 | #define __MUTEX_INITIALIZER(lockname) \ |
||
2161 | serge | 66 | { .wait_list = LIST_HEAD_INIT(lockname.wait_list), \ |
67 | .count = ATOMIC_INIT(1) \ |
||
68 | } |
||
1967 | serge | 69 | |
70 | #define DEFINE_MUTEX(mutexname) \ |
||
71 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) |
||
72 | |||
1616 | serge | 73 | void __attribute__ ((fastcall)) __attribute__ ((dllimport)) |
74 | mutex_init(struct mutex*)__asm__("MutexInit"); |
||
75 | void __attribute__ ((fastcall)) __attribute__ ((dllimport)) |
||
76 | mutex_lock(struct mutex*)__asm__("MutexLock"); |
||
77 | void __attribute__ ((fastcall)) __attribute__ ((dllimport)) |
||
78 | mutex_unlock(struct mutex*)__asm__("MutexUnlock"); |
||
79 | |||
3391 | Serge | 80 | static inline int mutex_lock_interruptible(struct mutex *lock) |
81 | { |
||
82 | mutex_lock(lock); |
||
83 | return 0; |
||
84 | } |
||
85 | |||
86 | # define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock) |
||
87 | |||
88 | |||
1616 | serge | 89 | /** |
90 | * mutex_is_locked - is the mutex locked |
||
91 | * @lock: the mutex to be queried |
||
92 | * |
||
93 | * Returns 1 if the mutex is locked, 0 if unlocked. |
||
94 | */ |
||
95 | static inline int mutex_is_locked(struct mutex *lock) |
||
96 | { |
||
97 | return atomic_read(&lock->count) != 1; |
||
98 | } |
||
99 | |||
5056 | serge | 100 | static inline int mutex_trylock(struct mutex *lock) |
101 | { |
||
102 | if (likely(atomic_cmpxchg(&lock->count, 1, 0) == 1)) |
||
103 | return 1; |
||
104 | return 0; |
||
105 | } |
||
106 | |||
107 | static inline void mutex_destroy(struct mutex *lock) |
||
108 | { |
||
109 | |||
110 | }; |
||
111 | |||
1616 | serge | 112 | #endif |