MySQL 8.2.0
Source Code Documentation
thr_mutex.h
Go to the documentation of this file.
1#ifndef THR_MUTEX_INCLUDED
2#define THR_MUTEX_INCLUDED
3
4/* Copyright (c) 2014, 2023, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is also distributed with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have included with MySQL.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License, version 2.0, for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
25
26/**
27 @file include/thr_mutex.h
28 MySQL mutex implementation.
29
30 There are three "layers":
31 1) native_mutex_*()
32 Functions that map directly down to OS primitives.
33 Windows - CriticalSection
34 Other OSes - pthread
35 2) my_mutex_*()
36 Functions that implement SAFE_MUTEX (default for debug),
37 Otherwise native_mutex_*() is used.
38 3) mysql_mutex_*()
39 Functions that include Performance Schema instrumentation.
40 See include/mysql/psi/mysql_thread.h
41*/
42
43#include <assert.h>
44#include <stddef.h>
45#include <stdlib.h>
46#include <sys/types.h>
47
48#include "my_inttypes.h"
49#include "my_macros.h"
50#include "my_thread.h"
51
52/*
53 The following are part of the services ABI:
54 - native_mutex_t
55 - my_mutex_t
56*/
58
59/* Define mutex types, see my_thr_init.c */
60#define MY_MUTEX_INIT_SLOW NULL
61
62/* Can be set in /usr/include/pthread.h */
63#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
64extern native_mutexattr_t my_fast_mutexattr;
65#define MY_MUTEX_INIT_FAST &my_fast_mutexattr
66#else
67#define MY_MUTEX_INIT_FAST NULL
68#endif
69
70/* Can be set in /usr/include/pthread.h */
71#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
72extern native_mutexattr_t my_errorcheck_mutexattr;
73#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
74#else
75#define MY_MUTEX_INIT_ERRCHK NULL
76#endif
77
78static inline int native_mutex_init(native_mutex_t *mutex,
79 const native_mutexattr_t *attr
80 [[maybe_unused]]) {
81#ifdef _WIN32
82 InitializeCriticalSection(mutex);
83 return 0;
84#else
85 return pthread_mutex_init(mutex, attr);
86#endif
87}
88
89static inline int native_mutex_lock(native_mutex_t *mutex) {
90#ifdef _WIN32
91 EnterCriticalSection(mutex);
92 return 0;
93#else
94 return pthread_mutex_lock(mutex);
95#endif
96}
97
98static inline int native_mutex_trylock(native_mutex_t *mutex) {
99#ifdef _WIN32
100 if (TryEnterCriticalSection(mutex)) {
101 /* Don't allow recursive lock */
102 if (mutex->RecursionCount > 1) {
103 LeaveCriticalSection(mutex);
104 return EBUSY;
105 }
106 return 0;
107 }
108 return EBUSY;
109#else
110 return pthread_mutex_trylock(mutex);
111#endif
112}
113
114static inline int native_mutex_unlock(native_mutex_t *mutex) {
115#ifdef _WIN32
116 LeaveCriticalSection(mutex);
117 return 0;
118#else
119 return pthread_mutex_unlock(mutex);
120#endif
121}
122
123static inline int native_mutex_destroy(native_mutex_t *mutex) {
124#ifdef _WIN32
125 DeleteCriticalSection(mutex);
126 return 0;
127#else
128 return pthread_mutex_destroy(mutex);
129#endif
130}
131
132#ifdef SAFE_MUTEX
133/* safe_mutex adds checking to mutex for easier debugging */
134struct safe_mutex_t {
135 native_mutex_t global, mutex;
136 const char *file;
137 uint line, count;
138 my_thread_t thread;
139};
140
141void safe_mutex_global_init();
142int safe_mutex_init(safe_mutex_t *mp, const native_mutexattr_t *attr,
143 const char *file, uint line);
144int safe_mutex_lock(safe_mutex_t *mp, bool try_lock, const char *file,
145 uint line);
146int safe_mutex_unlock(safe_mutex_t *mp, const char *file, uint line);
147int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line);
148
149static inline void safe_mutex_assert_owner(safe_mutex_t *mp) {
150 assert(mp != nullptr);
151 native_mutex_lock(&mp->global);
152 assert(mp->count > 0 && my_thread_equal(my_thread_self(), mp->thread));
153 native_mutex_unlock(&mp->global);
154}
155
156static inline void safe_mutex_assert_not_owner(safe_mutex_t *mp) {
157 assert(mp != nullptr);
158 native_mutex_lock(&mp->global);
159 assert(!mp->count || !my_thread_equal(my_thread_self(), mp->thread));
160 native_mutex_unlock(&mp->global);
161}
162#endif /* SAFE_MUTEX */
163
164static inline int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr
165#ifdef SAFE_MUTEX
166 ,
167 const char *file, uint line
168#endif
169) {
170#ifdef SAFE_MUTEX
171 assert(mp != nullptr);
172 mp->m_u.m_safe_ptr = (safe_mutex_t *)malloc(sizeof(safe_mutex_t));
173 return safe_mutex_init(mp->m_u.m_safe_ptr, attr, file, line);
174#else
175 return native_mutex_init(&mp->m_u.m_native, attr);
176#endif
177}
178
179static inline int my_mutex_lock(my_mutex_t *mp
180#ifdef SAFE_MUTEX
181 ,
182 const char *file, uint line
183#endif
184) {
185#ifdef SAFE_MUTEX
186 assert(mp != nullptr);
187 assert(mp->m_u.m_safe_ptr != nullptr);
188 return safe_mutex_lock(mp->m_u.m_safe_ptr, false, file, line);
189#else
190 return native_mutex_lock(&mp->m_u.m_native);
191#endif
192}
193
194static inline int my_mutex_trylock(my_mutex_t *mp
195#ifdef SAFE_MUTEX
196 ,
197 const char *file, uint line
198#endif
199) {
200#ifdef SAFE_MUTEX
201 assert(mp != nullptr);
202 assert(mp->m_u.m_safe_ptr != nullptr);
203 return safe_mutex_lock(mp->m_u.m_safe_ptr, true, file, line);
204#else
205 return native_mutex_trylock(&mp->m_u.m_native);
206#endif
207}
208
209static inline int my_mutex_unlock(my_mutex_t *mp
210#ifdef SAFE_MUTEX
211 ,
212 const char *file, uint line
213#endif
214) {
215#ifdef SAFE_MUTEX
216 assert(mp != nullptr);
217 assert(mp->m_u.m_safe_ptr != nullptr);
218 return safe_mutex_unlock(mp->m_u.m_safe_ptr, file, line);
219#else
220 return native_mutex_unlock(&mp->m_u.m_native);
221#endif
222}
223
224static inline int my_mutex_destroy(my_mutex_t *mp
225#ifdef SAFE_MUTEX
226 ,
227 const char *file, uint line
228#endif
229) {
230#ifdef SAFE_MUTEX
231 assert(mp != nullptr);
232 assert(mp->m_u.m_safe_ptr != nullptr);
233 int rc = safe_mutex_destroy(mp->m_u.m_safe_ptr, file, line);
234 free(mp->m_u.m_safe_ptr);
235 mp->m_u.m_safe_ptr = nullptr;
236 return rc;
237#else
238 return native_mutex_destroy(&mp->m_u.m_native);
239#endif
240}
241
242#endif /* THR_MUTEX_INCLUDED */
#define malloc(A)
Definition: lexyy.cc:914
#define free(A)
Definition: lexyy.cc:915
Some integer typedefs for easier portability.
Some common macros.
Defines to make different thread packages compatible.
static my_thread_t my_thread_self()
Definition: my_thread.h:74
static int my_thread_equal(my_thread_t t1, my_thread_t t2)
Definition: my_thread.h:82
pthread_t my_thread_t
Definition: my_thread_bits.h:47
static int count
Definition: myisam_ftdump.cc:44
Definition: os0file.h:88
Definition: thr_mutex_bits.h:60
union my_mutex_t::u m_u
static int my_mutex_init(my_mutex_t *mp, const native_mutexattr_t *attr)
Definition: thr_mutex.h:164
static int native_mutex_unlock(native_mutex_t *mutex)
Definition: thr_mutex.h:114
static int native_mutex_destroy(native_mutex_t *mutex)
Definition: thr_mutex.h:123
static int my_mutex_destroy(my_mutex_t *mp)
Definition: thr_mutex.h:224
static int native_mutex_trylock(native_mutex_t *mutex)
Definition: thr_mutex.h:98
static int native_mutex_lock(native_mutex_t *mutex)
Definition: thr_mutex.h:89
static int native_mutex_init(native_mutex_t *mutex, const native_mutexattr_t *attr)
Definition: thr_mutex.h:78
static int my_mutex_lock(my_mutex_t *mp)
Definition: thr_mutex.h:179
static int my_mutex_trylock(my_mutex_t *mp)
Definition: thr_mutex.h:194
static int my_mutex_unlock(my_mutex_t *mp)
Definition: thr_mutex.h:209
ABI for thd_mutex.
pthread_mutex_t native_mutex_t
Definition: thr_mutex_bits.h:54
pthread_mutexattr_t native_mutexattr_t
Definition: thr_mutex_bits.h:55
native_mutex_t m_native
Definition: thr_mutex_bits.h:62
safe_mutex_t * m_safe_ptr
Definition: thr_mutex_bits.h:63