Rev 3391 | Rev 5270 | Go to most recent revision | 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 | |||
13 | #include |
||
14 | #include |
||
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; |
||
2161 | serge | 47 | atomic_t count; |
1616 | serge | 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 | |||
1967 | serge | 59 | |
60 | #define __MUTEX_INITIALIZER(lockname) \ |
||
2161 | serge | 61 | { .wait_list = LIST_HEAD_INIT(lockname.wait_list), \ |
62 | .count = ATOMIC_INIT(1) \ |
||
63 | } |
||
1967 | serge | 64 | |
65 | #define DEFINE_MUTEX(mutexname) \ |
||
66 | struct mutex mutexname = __MUTEX_INITIALIZER(mutexname) |
||
67 | |||
1616 | serge | 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 | |||
3391 | Serge | 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 | |||
1616 | serge | 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 | |||
5056 | serge | 95 | static inline int mutex_trylock(struct mutex *lock) |
96 | { |
||
97 | if (likely(atomic_cmpxchg(&lock->count, 1, 0) == 1)) |
||
98 | return 1; |
||
99 | return 0; |
||
100 | } |
||
101 | |||
102 | static inline void mutex_destroy(struct mutex *lock) |
||
103 | { |
||
104 | |||
105 | }; |
||
106 | |||
1616 | serge | 107 | #endif |