Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
23f78d4a IM |
2 | /* |
3 | * RT Mutexes: blocking mutual exclusion locks with PI support | |
4 | * | |
5 | * started by Ingo Molnar and Thomas Gleixner: | |
6 | * | |
7 | * Copyright (C) 2004-2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | |
8 | * Copyright (C) 2006, Timesys Corp., Thomas Gleixner <tglx@timesys.com> | |
9 | * | |
10 | * This file contains the public data structure and API definitions. | |
11 | */ | |
12 | ||
13 | #ifndef __LINUX_RT_MUTEX_H | |
14 | #define __LINUX_RT_MUTEX_H | |
15 | ||
6bc8996a | 16 | #include <linux/compiler.h> |
23f78d4a | 17 | #include <linux/linkage.h> |
e4e17af3 | 18 | #include <linux/rbtree_types.h> |
a403abbd | 19 | #include <linux/spinlock_types_raw.h> |
23f78d4a | 20 | |
4f0e056f DY |
21 | extern int max_lock_depth; /* for sysctl */ |
22 | ||
830e6acc PZ |
23 | struct rt_mutex_base { |
24 | raw_spinlock_t wait_lock; | |
25 | struct rb_root_cached waiters; | |
26 | struct task_struct *owner; | |
27 | }; | |
28 | ||
29 | #define __RT_MUTEX_BASE_INITIALIZER(rtbasename) \ | |
30 | { \ | |
31 | .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(rtbasename.wait_lock), \ | |
32 | .waiters = RB_ROOT_CACHED, \ | |
33 | .owner = NULL \ | |
34 | } | |
35 | ||
6bc8996a TG |
36 | /** |
37 | * rt_mutex_base_is_locked - is the rtmutex locked | |
38 | * @lock: the mutex to be queried | |
39 | * | |
40 | * Returns true if the mutex is locked, false if unlocked. | |
41 | */ | |
42 | static inline bool rt_mutex_base_is_locked(struct rt_mutex_base *lock) | |
43 | { | |
44 | return READ_ONCE(lock->owner) != NULL; | |
45 | } | |
46 | ||
830e6acc PZ |
47 | extern void rt_mutex_base_init(struct rt_mutex_base *rtb); |
48 | ||
45f8bde0 | 49 | /** |
23f78d4a IM |
50 | * The rt_mutex structure |
51 | * | |
52 | * @wait_lock: spinlock to protect the structure | |
a23ba907 DB |
53 | * @waiters: rbtree root to enqueue waiters in priority order; |
54 | * caches top-waiter (leftmost node). | |
23f78d4a IM |
55 | * @owner: the mutex owner |
56 | */ | |
57 | struct rt_mutex { | |
830e6acc | 58 | struct rt_mutex_base rtmutex; |
f5694788 PZ |
59 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
60 | struct lockdep_map dep_map; | |
61 | #endif | |
23f78d4a IM |
62 | }; |
63 | ||
64 | struct rt_mutex_waiter; | |
65 | struct hrtimer_sleeper; | |
66 | ||
e7eebaf6 | 67 | #ifdef CONFIG_DEBUG_RT_MUTEXES |
8188d74e | 68 | extern void rt_mutex_debug_task_free(struct task_struct *tsk); |
e7eebaf6 | 69 | #else |
8188d74e | 70 | static inline void rt_mutex_debug_task_free(struct task_struct *tsk) { } |
e7eebaf6 IM |
71 | #endif |
72 | ||
199cacd1 | 73 | #define rt_mutex_init(mutex) \ |
f5694788 PZ |
74 | do { \ |
75 | static struct lock_class_key __key; \ | |
76 | __rt_mutex_init(mutex, __func__, &__key); \ | |
77 | } while (0) | |
78 | ||
f5694788 | 79 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
b41cda03 TG |
80 | #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ |
81 | .dep_map = { \ | |
82 | .name = #mutexname, \ | |
83 | .wait_type_inner = LD_WAIT_SLEEP, \ | |
84 | } | |
f5694788 PZ |
85 | #else |
86 | #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) | |
87 | #endif | |
88 | ||
b41cda03 TG |
89 | #define __RT_MUTEX_INITIALIZER(mutexname) \ |
90 | { \ | |
830e6acc | 91 | .rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex), \ |
b41cda03 TG |
92 | __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ |
93 | } | |
23f78d4a IM |
94 | |
95 | #define DEFINE_RT_MUTEX(mutexname) \ | |
96 | struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) | |
97 | ||
f5694788 | 98 | extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key); |
23f78d4a | 99 | |
62cedf3e PR |
100 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
101 | extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass); | |
a3642021 | 102 | extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock); |
62cedf3e | 103 | #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0) |
a3642021 SAS |
104 | #define rt_mutex_lock_nest_lock(lock, nest_lock) \ |
105 | do { \ | |
106 | typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \ | |
107 | _rt_mutex_lock_nest_lock(lock, &(nest_lock)->dep_map); \ | |
108 | } while (0) | |
109 | ||
62cedf3e | 110 | #else |
23f78d4a | 111 | extern void rt_mutex_lock(struct rt_mutex *lock); |
62cedf3e | 112 | #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock) |
a3642021 | 113 | #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock) |
62cedf3e PR |
114 | #endif |
115 | ||
c051b21f | 116 | extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); |
a3642021 | 117 | extern int rt_mutex_lock_killable(struct rt_mutex *lock); |
23f78d4a IM |
118 | extern int rt_mutex_trylock(struct rt_mutex *lock); |
119 | ||
120 | extern void rt_mutex_unlock(struct rt_mutex *lock); | |
121 | ||
23f78d4a | 122 | #endif |