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