Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Mutexes: blocking mutual exclusion locks
0004  *
0005  * started by Ingo Molnar:
0006  *
0007  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
0008  *
0009  * This file contains the main data structure and API definitions.
0010  */
0011 #ifndef __LINUX_MUTEX_H
0012 #define __LINUX_MUTEX_H
0013 
0014 #include <asm/current.h>
0015 #include <linux/list.h>
0016 #include <linux/spinlock_types.h>
0017 #include <linux/lockdep.h>
0018 #include <linux/atomic.h>
0019 #include <asm/processor.h>
0020 #include <linux/osq_lock.h>
0021 #include <linux/debug_locks.h>
0022 
0023 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0024 # define __DEP_MAP_MUTEX_INITIALIZER(lockname)          \
0025         , .dep_map = {                  \
0026             .name = #lockname,          \
0027             .wait_type_inner = LD_WAIT_SLEEP,   \
0028         }
0029 #else
0030 # define __DEP_MAP_MUTEX_INITIALIZER(lockname)
0031 #endif
0032 
0033 #ifndef CONFIG_PREEMPT_RT
0034 
0035 /*
0036  * Simple, straightforward mutexes with strict semantics:
0037  *
0038  * - only one task can hold the mutex at a time
0039  * - only the owner can unlock the mutex
0040  * - multiple unlocks are not permitted
0041  * - recursive locking is not permitted
0042  * - a mutex object must be initialized via the API
0043  * - a mutex object must not be initialized via memset or copying
0044  * - task may not exit with mutex held
0045  * - memory areas where held locks reside must not be freed
0046  * - held mutexes must not be reinitialized
0047  * - mutexes may not be used in hardware or software interrupt
0048  *   contexts such as tasklets and timers
0049  *
0050  * These semantics are fully enforced when DEBUG_MUTEXES is
0051  * enabled. Furthermore, besides enforcing the above rules, the mutex
0052  * debugging code also implements a number of additional features
0053  * that make lock debugging easier and faster:
0054  *
0055  * - uses symbolic names of mutexes, whenever they are printed in debug output
0056  * - point-of-acquire tracking, symbolic lookup of function names
0057  * - list of all locks held in the system, printout of them
0058  * - owner tracking
0059  * - detects self-recursing locks and prints out all relevant info
0060  * - detects multi-task circular deadlocks and prints out all affected
0061  *   locks and tasks (and only those tasks)
0062  */
0063 struct mutex {
0064     atomic_long_t       owner;
0065     raw_spinlock_t      wait_lock;
0066 #ifdef CONFIG_MUTEX_SPIN_ON_OWNER
0067     struct optimistic_spin_queue osq; /* Spinner MCS lock */
0068 #endif
0069     struct list_head    wait_list;
0070 #ifdef CONFIG_DEBUG_MUTEXES
0071     void            *magic;
0072 #endif
0073 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0074     struct lockdep_map  dep_map;
0075 #endif
0076 };
0077 
0078 #ifdef CONFIG_DEBUG_MUTEXES
0079 
0080 #define __DEBUG_MUTEX_INITIALIZER(lockname)             \
0081     , .magic = &lockname
0082 
0083 extern void mutex_destroy(struct mutex *lock);
0084 
0085 #else
0086 
0087 # define __DEBUG_MUTEX_INITIALIZER(lockname)
0088 
0089 static inline void mutex_destroy(struct mutex *lock) {}
0090 
0091 #endif
0092 
0093 /**
0094  * mutex_init - initialize the mutex
0095  * @mutex: the mutex to be initialized
0096  *
0097  * Initialize the mutex to unlocked state.
0098  *
0099  * It is not allowed to initialize an already locked mutex.
0100  */
0101 #define mutex_init(mutex)                       \
0102 do {                                    \
0103     static struct lock_class_key __key;             \
0104                                     \
0105     __mutex_init((mutex), #mutex, &__key);              \
0106 } while (0)
0107 
0108 #define __MUTEX_INITIALIZER(lockname) \
0109         { .owner = ATOMIC_LONG_INIT(0) \
0110         , .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(lockname.wait_lock) \
0111         , .wait_list = LIST_HEAD_INIT(lockname.wait_list) \
0112         __DEBUG_MUTEX_INITIALIZER(lockname) \
0113         __DEP_MAP_MUTEX_INITIALIZER(lockname) }
0114 
0115 #define DEFINE_MUTEX(mutexname) \
0116     struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
0117 
0118 extern void __mutex_init(struct mutex *lock, const char *name,
0119              struct lock_class_key *key);
0120 
0121 /**
0122  * mutex_is_locked - is the mutex locked
0123  * @lock: the mutex to be queried
0124  *
0125  * Returns true if the mutex is locked, false if unlocked.
0126  */
0127 extern bool mutex_is_locked(struct mutex *lock);
0128 
0129 #else /* !CONFIG_PREEMPT_RT */
0130 /*
0131  * Preempt-RT variant based on rtmutexes.
0132  */
0133 #include <linux/rtmutex.h>
0134 
0135 struct mutex {
0136     struct rt_mutex_base    rtmutex;
0137 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0138     struct lockdep_map  dep_map;
0139 #endif
0140 };
0141 
0142 #define __MUTEX_INITIALIZER(mutexname)                  \
0143 {                                   \
0144     .rtmutex = __RT_MUTEX_BASE_INITIALIZER(mutexname.rtmutex)   \
0145     __DEP_MAP_MUTEX_INITIALIZER(mutexname)              \
0146 }
0147 
0148 #define DEFINE_MUTEX(mutexname)                     \
0149     struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
0150 
0151 extern void __mutex_rt_init(struct mutex *lock, const char *name,
0152                 struct lock_class_key *key);
0153 extern int mutex_trylock(struct mutex *lock);
0154 
0155 static inline void mutex_destroy(struct mutex *lock) { }
0156 
0157 #define mutex_is_locked(l)  rt_mutex_base_is_locked(&(l)->rtmutex)
0158 
0159 #define __mutex_init(mutex, name, key)          \
0160 do {                            \
0161     rt_mutex_base_init(&(mutex)->rtmutex);      \
0162     __mutex_rt_init((mutex), name, key);        \
0163 } while (0)
0164 
0165 #define mutex_init(mutex)               \
0166 do {                            \
0167     static struct lock_class_key __key;     \
0168                             \
0169     __mutex_init((mutex), #mutex, &__key);      \
0170 } while (0)
0171 #endif /* CONFIG_PREEMPT_RT */
0172 
0173 /*
0174  * See kernel/locking/mutex.c for detailed documentation of these APIs.
0175  * Also see Documentation/locking/mutex-design.rst.
0176  */
0177 #ifdef CONFIG_DEBUG_LOCK_ALLOC
0178 extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass);
0179 extern void _mutex_lock_nest_lock(struct mutex *lock, struct lockdep_map *nest_lock);
0180 
0181 extern int __must_check mutex_lock_interruptible_nested(struct mutex *lock,
0182                     unsigned int subclass);
0183 extern int __must_check mutex_lock_killable_nested(struct mutex *lock,
0184                     unsigned int subclass);
0185 extern void mutex_lock_io_nested(struct mutex *lock, unsigned int subclass);
0186 
0187 #define mutex_lock(lock) mutex_lock_nested(lock, 0)
0188 #define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)
0189 #define mutex_lock_killable(lock) mutex_lock_killable_nested(lock, 0)
0190 #define mutex_lock_io(lock) mutex_lock_io_nested(lock, 0)
0191 
0192 #define mutex_lock_nest_lock(lock, nest_lock)               \
0193 do {                                    \
0194     typecheck(struct lockdep_map *, &(nest_lock)->dep_map); \
0195     _mutex_lock_nest_lock(lock, &(nest_lock)->dep_map);     \
0196 } while (0)
0197 
0198 #else
0199 extern void mutex_lock(struct mutex *lock);
0200 extern int __must_check mutex_lock_interruptible(struct mutex *lock);
0201 extern int __must_check mutex_lock_killable(struct mutex *lock);
0202 extern void mutex_lock_io(struct mutex *lock);
0203 
0204 # define mutex_lock_nested(lock, subclass) mutex_lock(lock)
0205 # define mutex_lock_interruptible_nested(lock, subclass) mutex_lock_interruptible(lock)
0206 # define mutex_lock_killable_nested(lock, subclass) mutex_lock_killable(lock)
0207 # define mutex_lock_nest_lock(lock, nest_lock) mutex_lock(lock)
0208 # define mutex_lock_io_nested(lock, subclass) mutex_lock_io(lock)
0209 #endif
0210 
0211 /*
0212  * NOTE: mutex_trylock() follows the spin_trylock() convention,
0213  *       not the down_trylock() convention!
0214  *
0215  * Returns 1 if the mutex has been acquired successfully, and 0 on contention.
0216  */
0217 extern int mutex_trylock(struct mutex *lock);
0218 extern void mutex_unlock(struct mutex *lock);
0219 
0220 extern int atomic_dec_and_mutex_lock(atomic_t *cnt, struct mutex *lock);
0221 
0222 #endif /* __LINUX_MUTEX_H */