1 /*****************************************************************************
2
3 Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2017, 2020, MariaDB Corporation.
5
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
8 Foundation; version 2 of the License.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
17
18 *****************************************************************************/
19
20 /******************************************************************//**
21 @file include/ut0mutex.h
22 Policy based mutexes.
23
24 Created 2012-03-24 Sunny Bains.
25 ***********************************************************************/
26
27 #ifndef UNIV_INNOCHECKSUM
28
29 #ifndef ut0mutex_h
30 #define ut0mutex_h
31
32 #include "sync0policy.h"
33 #include "ib0mutex.h"
34
35 /** Create a typedef using the MutexType<PolicyType>
36 @param[in] M Mutex type
37 @param[in[ P Policy type
38 @param[in] T The resulting typedef alias */
39 #define UT_MUTEX_TYPE(M, P, T) typedef PolicyMutex<M<P> > T;
40
41 # ifdef HAVE_IB_LINUX_FUTEX
42 UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex);
43 UT_MUTEX_TYPE(TTASFutexMutex, BlockMutexPolicy, BlockFutexMutex);
44 # endif /* HAVE_IB_LINUX_FUTEX */
45
46 UT_MUTEX_TYPE(TTASMutex, GenericPolicy, SpinMutex);
47 UT_MUTEX_TYPE(TTASMutex, BlockMutexPolicy, BlockSpinMutex);
48
49 UT_MUTEX_TYPE(OSTrackMutex, GenericPolicy, SysMutex);
50 UT_MUTEX_TYPE(OSTrackMutex, BlockMutexPolicy, BlockSysMutex);
51
52 UT_MUTEX_TYPE(TTASEventMutex, GenericPolicy, SyncArrayMutex);
53 UT_MUTEX_TYPE(TTASEventMutex, BlockMutexPolicy, BlockSyncArrayMutex);
54
55 #ifdef MUTEX_FUTEX
56 /** The default mutex type. */
57 typedef FutexMutex ib_mutex_t;
58 typedef BlockFutexMutex ib_bpmutex_t;
59 #define MUTEX_TYPE "Uses futexes"
60 #elif defined(MUTEX_SYS)
61 typedef SysMutex ib_mutex_t;
62 typedef BlockSysMutex ib_bpmutex_t;
63 #define MUTEX_TYPE "Uses system mutexes"
64 #elif defined(MUTEX_EVENT)
65 typedef SyncArrayMutex ib_mutex_t;
66 typedef BlockSyncArrayMutex ib_bpmutex_t;
67 #define MUTEX_TYPE "Uses event mutexes"
68 #else
69 #error "ib_mutex_t type is unknown"
70 #endif /* MUTEX_FUTEX */
71
72 extern uint srv_spin_wait_delay;
73 extern ulong srv_n_spin_wait_rounds;
74
75 #define mutex_create(I, M) mutex_init((M), (I), \
76 __FILE__, __LINE__)
77
78 #define mutex_enter_loc(M,file,line) (M)->enter( \
79 uint32_t(srv_n_spin_wait_rounds), \
80 uint32_t(srv_spin_wait_delay), \
81 file, line)
82 #define mutex_enter(M) mutex_enter_loc(M, __FILE__, __LINE__)
83
84 #define mutex_enter_nospin(M) (M)->enter( \
85 0, \
86 0, \
87 __FILE__, uint32_t(__LINE__))
88
89 #define mutex_enter_nowait(M) (M)->trylock(__FILE__, \
90 uint32_t(__LINE__))
91
92 #define mutex_exit(M) (M)->exit()
93
94 #define mutex_free(M) mutex_destroy(M)
95
96 #ifdef UNIV_DEBUG
97 /**
98 Checks that the mutex has been initialized. */
99 #define mutex_validate(M) (M)->validate()
100
101 /**
102 Checks that the current thread owns the mutex. Works only
103 in the debug version. */
104 #define mutex_own(M) (M)->is_owned()
105 #else
106 #define mutex_own(M) /* No op */
107 #define mutex_validate(M) /* No op */
108 #endif /* UNIV_DEBUG */
109
110 /** Iterate over the mutex meta data */
111 class MutexMonitor {
112 public:
113 /** Constructor */
MutexMonitor()114 MutexMonitor() { }
115
116 /** Destructor */
~MutexMonitor()117 ~MutexMonitor() { }
118
119 /** Enable the mutex monitoring */
120 void enable();
121
122 /** Disable the mutex monitoring */
123 void disable();
124
125 /** Reset the mutex monitoring values */
126 void reset();
127
128 /** Invoke the callback for each active mutex collection
129 @param[in,out] callback Functor to call
130 @return false if callback returned false */
131 template<typename Callback>
iterate(Callback & callback)132 bool iterate(Callback& callback) const
133 UNIV_NOTHROW
134 {
135 LatchMetaData::iterator end = latch_meta.end();
136
137 for (LatchMetaData::iterator it = latch_meta.begin();
138 it != end;
139 ++it) {
140
141 /* Some of the slots will be null in non-debug mode */
142
143 if (latch_meta_t* l= *it) {
144 if (!callback(*l)) {
145 return false;
146 }
147 }
148 }
149
150 return(true);
151 }
152 };
153
154 /** Defined in sync0sync.cc */
155 extern MutexMonitor mutex_monitor;
156
157 /**
158 Creates, or rather, initializes a mutex object in a specified memory
159 location (which must be appropriately aligned). The mutex is initialized
160 in the reset state. Explicit freeing of the mutex with mutex_free is
161 necessary only if the memory block containing it is freed.
162 Add the mutex instance to the global mutex list.
163 @param[in,out] mutex mutex to initialise
164 @param[in] id The mutex ID (Latch ID)
165 @param[in] filename Filename from where it was called
166 @param[in] line Line number in filename from where called */
167 template <typename Mutex>
mutex_init(Mutex * mutex,latch_id_t id,const char * file_name,uint32_t line)168 void mutex_init(
169 Mutex* mutex,
170 latch_id_t id,
171 const char* file_name,
172 uint32_t line)
173 {
174 new(mutex) Mutex();
175
176 mutex->init(id, file_name, line);
177 }
178
179 /**
180 Removes a mutex instance from the mutex list. The mutex is checked to
181 be in the reset state.
182 @param[in,out] mutex mutex instance to destroy */
183 template <typename Mutex>
mutex_destroy(Mutex * mutex)184 void mutex_destroy(
185 Mutex* mutex)
186 {
187 mutex->destroy();
188 }
189
190 #endif /* ut0mutex_h */
191
192 #endif /* UNIV_INNOCHECKSUM */
193