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 typedef OSMutex EventMutex;
42
43 # ifdef HAVE_IB_LINUX_FUTEX
44 UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex);
45 UT_MUTEX_TYPE(TTASFutexMutex, BlockMutexPolicy, BlockFutexMutex);
46 # endif /* HAVE_IB_LINUX_FUTEX */
47
48 UT_MUTEX_TYPE(TTASMutex, GenericPolicy, SpinMutex);
49 UT_MUTEX_TYPE(TTASMutex, BlockMutexPolicy, BlockSpinMutex);
50
51 UT_MUTEX_TYPE(OSTrackMutex, GenericPolicy, SysMutex);
52 UT_MUTEX_TYPE(OSTrackMutex, BlockMutexPolicy, BlockSysMutex);
53
54 UT_MUTEX_TYPE(TTASEventMutex, GenericPolicy, SyncArrayMutex);
55 UT_MUTEX_TYPE(TTASEventMutex, BlockMutexPolicy, BlockSyncArrayMutex);
56
57 #ifdef MUTEX_FUTEX
58 /** The default mutex type. */
59 typedef FutexMutex ib_mutex_t;
60 typedef BlockFutexMutex ib_bpmutex_t;
61 #define MUTEX_TYPE "Uses futexes"
62 #elif defined(MUTEX_SYS)
63 typedef SysMutex ib_mutex_t;
64 typedef BlockSysMutex ib_bpmutex_t;
65 #define MUTEX_TYPE "Uses system mutexes"
66 #elif defined(MUTEX_EVENT)
67 typedef SyncArrayMutex ib_mutex_t;
68 typedef BlockSyncArrayMutex ib_bpmutex_t;
69 #define MUTEX_TYPE "Uses event mutexes"
70 #else
71 #error "ib_mutex_t type is unknown"
72 #endif /* MUTEX_FUTEX */
73
74 extern uint srv_spin_wait_delay;
75 extern ulong srv_n_spin_wait_rounds;
76
77 #define mutex_create(I, M) mutex_init((M), (I), \
78 __FILE__, __LINE__)
79
80 #define mutex_enter_loc(M,file,line) (M)->enter( \
81 uint32_t(srv_n_spin_wait_rounds), \
82 uint32_t(srv_spin_wait_delay), \
83 file, line)
84 #define mutex_enter(M) mutex_enter_loc(M, __FILE__, __LINE__)
85
86 #define mutex_enter_nospin(M) (M)->enter( \
87 0, \
88 0, \
89 __FILE__, uint32_t(__LINE__))
90
91 #define mutex_enter_nowait(M) (M)->trylock(__FILE__, \
92 uint32_t(__LINE__))
93
94 #define mutex_exit(M) (M)->exit()
95
96 #define mutex_free(M) mutex_destroy(M)
97
98 #ifdef UNIV_DEBUG
99 /**
100 Checks that the mutex has been initialized. */
101 #define mutex_validate(M) (M)->validate()
102
103 /**
104 Checks that the current thread owns the mutex. Works only
105 in the debug version. */
106 #define mutex_own(M) (M)->is_owned()
107 #else
108 #define mutex_own(M) /* No op */
109 #define mutex_validate(M) /* No op */
110 #endif /* UNIV_DEBUG */
111
112 /** Iterate over the mutex meta data */
113 class MutexMonitor {
114 public:
115 /** Constructor */
MutexMonitor()116 MutexMonitor() { }
117
118 /** Destructor */
~MutexMonitor()119 ~MutexMonitor() { }
120
121 /** Enable the mutex monitoring */
122 void enable();
123
124 /** Disable the mutex monitoring */
125 void disable();
126
127 /** Reset the mutex monitoring values */
128 void reset();
129
130 /** Invoke the callback for each active mutex collection
131 @param[in,out] callback Functor to call
132 @return false if callback returned false */
133 template<typename Callback>
iterate(Callback & callback)134 bool iterate(Callback& callback) const
135 UNIV_NOTHROW
136 {
137 LatchMetaData::iterator end = latch_meta.end();
138
139 for (LatchMetaData::iterator it = latch_meta.begin();
140 it != end;
141 ++it) {
142
143 /* Some of the slots will be null in non-debug mode */
144
145 if (latch_meta_t* l= *it) {
146 if (!callback(*l)) {
147 return false;
148 }
149 }
150 }
151
152 return(true);
153 }
154 };
155
156 /** Defined in sync0sync.cc */
157 extern MutexMonitor mutex_monitor;
158
159 /**
160 Creates, or rather, initializes a mutex object in a specified memory
161 location (which must be appropriately aligned). The mutex is initialized
162 in the reset state. Explicit freeing of the mutex with mutex_free is
163 necessary only if the memory block containing it is freed.
164 Add the mutex instance to the global mutex list.
165 @param[in,out] mutex mutex to initialise
166 @param[in] id The mutex ID (Latch ID)
167 @param[in] filename Filename from where it was called
168 @param[in] line Line number in filename from where called */
169 template <typename Mutex>
mutex_init(Mutex * mutex,latch_id_t id,const char * file_name,uint32_t line)170 void mutex_init(
171 Mutex* mutex,
172 latch_id_t id,
173 const char* file_name,
174 uint32_t line)
175 {
176 new(mutex) Mutex();
177
178 mutex->init(id, file_name, line);
179 }
180
181 /**
182 Removes a mutex instance from the mutex list. The mutex is checked to
183 be in the reset state.
184 @param[in,out] mutex mutex instance to destroy */
185 template <typename Mutex>
mutex_destroy(Mutex * mutex)186 void mutex_destroy(
187 Mutex* mutex)
188 {
189 mutex->destroy();
190 }
191
192 #endif /* ut0mutex_h */
193
194 #endif /* UNIV_INNOCHECKSUM */
195