1 | /* SPDX-License-Identifier: GPL-2.0 */ |
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 | |
16 | #include <linux/compiler.h> |
17 | #include <linux/linkage.h> |
18 | #include <linux/rbtree_types.h> |
19 | #include <linux/spinlock_types_raw.h> |
20 | |
21 | extern int max_lock_depth; /* for sysctl */ |
22 | |
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 | |
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 | |
47 | extern void rt_mutex_base_init(struct rt_mutex_base *rtb); |
48 | |
49 | /** |
50 | * The rt_mutex structure |
51 | * |
52 | * @wait_lock: spinlock to protect the structure |
53 | * @waiters: rbtree root to enqueue waiters in priority order; |
54 | * caches top-waiter (leftmost node). |
55 | * @owner: the mutex owner |
56 | */ |
57 | struct rt_mutex { |
58 | struct rt_mutex_base rtmutex; |
59 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
60 | struct lockdep_map dep_map; |
61 | #endif |
62 | }; |
63 | |
64 | struct rt_mutex_waiter; |
65 | struct hrtimer_sleeper; |
66 | |
67 | #ifdef CONFIG_DEBUG_RT_MUTEXES |
68 | extern void rt_mutex_debug_task_free(struct task_struct *tsk); |
69 | #else |
70 | static inline void rt_mutex_debug_task_free(struct task_struct *tsk) { } |
71 | #endif |
72 | |
73 | #define rt_mutex_init(mutex) \ |
74 | do { \ |
75 | static struct lock_class_key __key; \ |
76 | __rt_mutex_init(mutex, __func__, &__key); \ |
77 | } while (0) |
78 | |
79 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
80 | #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ |
81 | .dep_map = { \ |
82 | .name = #mutexname, \ |
83 | .wait_type_inner = LD_WAIT_SLEEP, \ |
84 | } |
85 | #else |
86 | #define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) |
87 | #endif |
88 | |
89 | #define __RT_MUTEX_INITIALIZER(mutexname) \ |
90 | { \ |
91 | .rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex), \ |
92 | __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \ |
93 | } |
94 | |
95 | #define DEFINE_RT_MUTEX(mutexname) \ |
96 | struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname) |
97 | |
98 | extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key); |
99 | |
100 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
101 | extern void rt_mutex_lock_nested(struct rt_mutex *lock, unsigned int subclass); |
102 | extern void _rt_mutex_lock_nest_lock(struct rt_mutex *lock, struct lockdep_map *nest_lock); |
103 | #define rt_mutex_lock(lock) rt_mutex_lock_nested(lock, 0) |
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 | |
110 | #else |
111 | extern void rt_mutex_lock(struct rt_mutex *lock); |
112 | #define rt_mutex_lock_nested(lock, subclass) rt_mutex_lock(lock) |
113 | #define rt_mutex_lock_nest_lock(lock, nest_lock) rt_mutex_lock(lock) |
114 | #endif |
115 | |
116 | extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); |
117 | extern int rt_mutex_lock_killable(struct rt_mutex *lock); |
118 | extern int rt_mutex_trylock(struct rt_mutex *lock); |
119 | |
120 | extern void rt_mutex_unlock(struct rt_mutex *lock); |
121 | |
122 | #endif |
123 | |