641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
1 |
/*****************************************************************************
|
2 |
||
3 |
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
|
|
4 |
Copyright (c) 2008, Google Inc.
|
|
5 |
||
6 |
Portions of this file contain modifications contributed and copyrighted by
|
|
7 |
Google, Inc. Those modifications are gratefully acknowledged and are described
|
|
8 |
briefly in the InnoDB documentation. The contributions by Google are
|
|
9 |
incorporated with their permission, and subject to the conditions contained in
|
|
10 |
the file COPYING.Google.
|
|
11 |
||
12 |
This program is free software; you can redistribute it and/or modify it under
|
|
13 |
the terms of the GNU General Public License as published by the Free Software
|
|
14 |
Foundation; version 2 of the License.
|
|
15 |
||
16 |
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
17 |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
18 |
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
19 |
||
20 |
You should have received a copy of the GNU General Public License along with
|
|
21 |
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
|
22 |
Place, Suite 330, Boston, MA 02111-1307 USA
|
|
23 |
||
24 |
*****************************************************************************/
|
|
25 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
26 |
/**************************************************//**
|
27 |
@file include/sync0rw.h
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
28 |
The read-write lock (for threads, not for database transactions)
|
29 |
||
30 |
Created 9/11/1995 Heikki Tuuri
|
|
31 |
*******************************************************/
|
|
32 |
||
33 |
#ifndef sync0rw_h
|
|
34 |
#define sync0rw_h
|
|
35 |
||
36 |
#include "univ.i" |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
37 |
#ifndef UNIV_HOTBACKUP
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
38 |
#include "ut0lst.h" |
39 |
#include "sync0sync.h" |
|
40 |
#include "os0sync.h" |
|
41 |
||
42 |
/* The following undef is to prevent a name conflict with a macro
|
|
43 |
in MySQL: */
|
|
44 |
#undef rw_lock_t
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
45 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
46 |
|
47 |
/* Latch types; these are used also in btr0btr.h: keep the numerical values
|
|
48 |
smaller than 30 and the order of the numerical values like below! */
|
|
49 |
#define RW_S_LATCH 1
|
|
50 |
#define RW_X_LATCH 2
|
|
51 |
#define RW_NO_LATCH 3
|
|
52 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
53 |
#ifndef UNIV_HOTBACKUP
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
54 |
/* We decrement lock_word by this amount for each x_lock. It is also the
|
55 |
start value for the lock_word, meaning that it limits the maximum number
|
|
56 |
of concurrent read locks before the rw_lock breaks. The current value of
|
|
57 |
0x00100000 allows 1,048,575 concurrent readers and 2047 recursive writers.*/
|
|
58 |
#define X_LOCK_DECR 0x00100000
|
|
59 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
60 |
typedef struct rw_lock_struct rw_lock_t; |
61 |
#ifdef UNIV_SYNC_DEBUG
|
|
62 |
typedef struct rw_lock_debug_struct rw_lock_debug_t; |
|
63 |
#endif /* UNIV_SYNC_DEBUG */ |
|
64 |
||
65 |
typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t; |
|
66 |
||
67 |
extern rw_lock_list_t rw_lock_list; |
|
68 |
extern mutex_t rw_lock_list_mutex; |
|
69 |
||
70 |
#ifdef UNIV_SYNC_DEBUG
|
|
71 |
/* The global mutex which protects debug info lists of all rw-locks.
|
|
72 |
To modify the debug info list of an rw-lock, this mutex has to be
|
|
73 |
||
74 |
acquired in addition to the mutex protecting the lock. */
|
|
75 |
extern mutex_t rw_lock_debug_mutex; |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
76 |
extern os_event_t rw_lock_debug_event; /*!< If deadlock detection does |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
77 |
not get immediately the mutex it
|
78 |
may wait for this event */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
79 |
extern ibool rw_lock_debug_waiters; /*!< This is set to TRUE, if |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
80 |
there may be waiters for the event */
|
81 |
#endif /* UNIV_SYNC_DEBUG */ |
|
82 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
83 |
/** number of spin waits on rw-latches,
|
84 |
resulted during exclusive (write) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
85 |
extern ib_int64_t rw_s_spin_wait_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
86 |
/** number of spin loop rounds on rw-latches,
|
87 |
resulted during exclusive (write) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
88 |
extern ib_int64_t rw_s_spin_round_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
89 |
/** number of unlocks (that unlock shared locks),
|
90 |
set only when UNIV_SYNC_PERF_STAT is defined */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
91 |
extern ib_int64_t rw_s_exit_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
92 |
/** number of OS waits on rw-latches,
|
93 |
resulted during shared (read) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
94 |
extern ib_int64_t rw_s_os_wait_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
95 |
/** number of spin waits on rw-latches,
|
96 |
resulted during shared (read) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
97 |
extern ib_int64_t rw_x_spin_wait_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
98 |
/** number of spin loop rounds on rw-latches,
|
99 |
resulted during shared (read) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
100 |
extern ib_int64_t rw_x_spin_round_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
101 |
/** number of OS waits on rw-latches,
|
102 |
resulted during exclusive (write) locks */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
103 |
extern ib_int64_t rw_x_os_wait_count; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
104 |
/** number of unlocks (that unlock exclusive locks),
|
105 |
set only when UNIV_SYNC_PERF_STAT is defined */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
106 |
extern ib_int64_t rw_x_exit_count; |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
107 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
108 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
109 |
Creates, or rather, initializes an rw-lock object in a specified memory
|
110 |
location (which must be appropriately aligned). The rw-lock is initialized
|
|
111 |
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
|
|
112 |
is necessary only if the memory block containing it is freed. */
|
|
113 |
#ifdef UNIV_DEBUG
|
|
114 |
# ifdef UNIV_SYNC_DEBUG
|
|
115 |
# define rw_lock_create(L, level) \
|
|
116 |
rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
|
|
117 |
# else /* UNIV_SYNC_DEBUG */ |
|
118 |
# define rw_lock_create(L, level) \
|
|
119 |
rw_lock_create_func((L), #L, __FILE__, __LINE__)
|
|
120 |
# endif /* UNIV_SYNC_DEBUG */ |
|
121 |
#else /* UNIV_DEBUG */ |
|
122 |
# define rw_lock_create(L, level) \
|
|
123 |
rw_lock_create_func((L), __FILE__, __LINE__)
|
|
124 |
#endif /* UNIV_DEBUG */ |
|
125 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
126 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
127 |
Creates, or rather, initializes an rw-lock object in a specified memory
|
128 |
location (which must be appropriately aligned). The rw-lock is initialized
|
|
129 |
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
|
|
130 |
is necessary only if the memory block containing it is freed. */
|
|
131 |
UNIV_INTERN
|
|
132 |
void
|
|
133 |
rw_lock_create_func( |
|
134 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
135 |
rw_lock_t* lock, /*!< in: pointer to memory */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
136 |
#ifdef UNIV_DEBUG
|
137 |
# ifdef UNIV_SYNC_DEBUG
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
138 |
ulint level, /*!< in: level */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
139 |
# endif /* UNIV_SYNC_DEBUG */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
140 |
const char* cmutex_name, /*!< in: mutex name */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
141 |
#endif /* UNIV_DEBUG */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
142 |
const char* cfile_name, /*!< in: file name where created */ |
143 |
ulint cline); /*!< in: file line where created */ |
|
144 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
145 |
Calling this function is obligatory only if the memory buffer containing
|
146 |
the rw-lock is freed. Removes an rw-lock object from the global list. The
|
|
147 |
rw-lock is checked to be in the non-locked state. */
|
|
148 |
UNIV_INTERN
|
|
149 |
void
|
|
150 |
rw_lock_free( |
|
151 |
/*=========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
152 |
rw_lock_t* lock); /*!< in: rw-lock */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
153 |
#ifdef UNIV_DEBUG
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
154 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
155 |
Checks that the rw-lock has been initialized and that there are no
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
156 |
simultaneous shared and exclusive locks.
|
157 |
@return TRUE */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
158 |
UNIV_INTERN
|
159 |
ibool
|
|
160 |
rw_lock_validate( |
|
161 |
/*=============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
162 |
rw_lock_t* lock); /*!< in: rw-lock */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
163 |
#endif /* UNIV_DEBUG */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
164 |
/**************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
165 |
NOTE! The following macros should be used in rw s-locking, not the
|
166 |
corresponding function. */
|
|
167 |
||
168 |
#define rw_lock_s_lock(M) rw_lock_s_lock_func(\
|
|
169 |
(M), 0, __FILE__, __LINE__)
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
170 |
/**************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
171 |
NOTE! The following macros should be used in rw s-locking, not the
|
172 |
corresponding function. */
|
|
173 |
||
174 |
#define rw_lock_s_lock_gen(M, P) rw_lock_s_lock_func(\
|
|
175 |
(M), (P), __FILE__, __LINE__)
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
176 |
/**************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
177 |
NOTE! The following macros should be used in rw s-locking, not the
|
178 |
corresponding function. */
|
|
179 |
||
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
180 |
#define rw_lock_s_lock_nowait(M, F, L) rw_lock_s_lock_low(\
|
181 |
(M), 0, (F), (L))
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
182 |
/******************************************************************//**
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
183 |
Low-level function which tries to lock an rw-lock in s-mode. Performs no
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
184 |
spinning.
|
185 |
@return TRUE if success */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
186 |
UNIV_INLINE
|
187 |
ibool
|
|
188 |
rw_lock_s_lock_low( |
|
189 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
190 |
rw_lock_t* lock, /*!< in: pointer to rw-lock */ |
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
191 |
ulint pass __attribute__((unused)), |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
192 |
/*!< in: pass value; != 0, if the lock will be
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
193 |
passed to another thread to unlock */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
194 |
const char* file_name, /*!< in: file name where lock requested */ |
195 |
ulint line); /*!< in: line where requested */ |
|
196 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
197 |
NOTE! Use the corresponding macro, not directly this function, except if
|
198 |
you supply the file name and line number. Lock an rw-lock in shared mode
|
|
199 |
for the current thread. If the rw-lock is locked in exclusive mode, or
|
|
200 |
there is an exclusive lock request waiting, the function spins a preset
|
|
201 |
time (controlled by SYNC_SPIN_ROUNDS), waiting for the lock, before
|
|
202 |
suspending the thread. */
|
|
203 |
UNIV_INLINE
|
|
204 |
void
|
|
205 |
rw_lock_s_lock_func( |
|
206 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
207 |
rw_lock_t* lock, /*!< in: pointer to rw-lock */ |
208 |
ulint pass, /*!< in: pass value; != 0, if the lock will |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
209 |
be passed to another thread to unlock */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
210 |
const char* file_name,/*!< in: file name where lock requested */ |
211 |
ulint line); /*!< in: line where requested */ |
|
212 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
213 |
NOTE! Use the corresponding macro, not directly this function! Lock an
|
214 |
rw-lock in exclusive mode for the current thread if the lock can be
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
215 |
obtained immediately.
|
216 |
@return TRUE if success */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
217 |
UNIV_INLINE
|
218 |
ibool
|
|
219 |
rw_lock_x_lock_func_nowait( |
|
220 |
/*=======================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
221 |
rw_lock_t* lock, /*!< in: pointer to rw-lock */ |
222 |
const char* file_name,/*!< in: file name where lock requested */ |
|
223 |
ulint line); /*!< in: line where requested */ |
|
224 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
225 |
Releases a shared mode lock. */
|
226 |
UNIV_INLINE
|
|
227 |
void
|
|
228 |
rw_lock_s_unlock_func( |
|
229 |
/*==================*/
|
|
230 |
#ifdef UNIV_SYNC_DEBUG
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
231 |
ulint pass, /*!< in: pass value; != 0, if the lock may have |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
232 |
been passed to another thread to unlock */
|
233 |
#endif
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
234 |
rw_lock_t* lock); /*!< in/out: rw-lock */ |
235 |
||
236 |
#ifdef UNIV_SYNC_DEBUG
|
|
237 |
# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
|
|
238 |
#else
|
|
239 |
# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
|
|
240 |
#endif
|
|
241 |
/*******************************************************************//**
|
|
242 |
Releases a shared mode lock. */
|
|
243 |
#define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
|
|
244 |
||
245 |
/**************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
246 |
NOTE! The following macro should be used in rw x-locking, not the
|
247 |
corresponding function. */
|
|
248 |
||
249 |
#define rw_lock_x_lock(M) rw_lock_x_lock_func(\
|
|
250 |
(M), 0, __FILE__, __LINE__)
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
251 |
/**************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
252 |
NOTE! The following macro should be used in rw x-locking, not the
|
253 |
corresponding function. */
|
|
254 |
||
255 |
#define rw_lock_x_lock_gen(M, P) rw_lock_x_lock_func(\
|
|
256 |
(M), (P), __FILE__, __LINE__)
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
257 |
/**************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
258 |
NOTE! The following macros should be used in rw x-locking, not the
|
259 |
corresponding function. */
|
|
260 |
||
261 |
#define rw_lock_x_lock_nowait(M) rw_lock_x_lock_func_nowait(\
|
|
262 |
(M), __FILE__, __LINE__)
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
263 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
264 |
NOTE! Use the corresponding macro, not directly this function! Lock an
|
265 |
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
|
|
266 |
in shared or exclusive mode, or there is an exclusive lock request waiting,
|
|
267 |
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
|
|
268 |
for the lock, before suspending the thread. If the same thread has an x-lock
|
|
269 |
on the rw-lock, locking succeed, with the following exception: if pass != 0,
|
|
270 |
only a single x-lock may be taken on the lock. NOTE: If the same thread has
|
|
271 |
an s-lock, locking does not succeed! */
|
|
272 |
UNIV_INTERN
|
|
273 |
void
|
|
274 |
rw_lock_x_lock_func( |
|
275 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
276 |
rw_lock_t* lock, /*!< in: pointer to rw-lock */ |
277 |
ulint pass, /*!< in: pass value; != 0, if the lock will |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
278 |
be passed to another thread to unlock */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
279 |
const char* file_name,/*!< in: file name where lock requested */ |
280 |
ulint line); /*!< in: line where requested */ |
|
281 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
282 |
Releases an exclusive mode lock. */
|
283 |
UNIV_INLINE
|
|
284 |
void
|
|
285 |
rw_lock_x_unlock_func( |
|
286 |
/*==================*/
|
|
287 |
#ifdef UNIV_SYNC_DEBUG
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
288 |
ulint pass, /*!< in: pass value; != 0, if the lock may have |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
289 |
been passed to another thread to unlock */
|
290 |
#endif
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
291 |
rw_lock_t* lock); /*!< in/out: rw-lock */ |
292 |
||
293 |
#ifdef UNIV_SYNC_DEBUG
|
|
294 |
# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
|
|
295 |
#else
|
|
296 |
# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
|
|
297 |
#endif
|
|
298 |
/*******************************************************************//**
|
|
299 |
Releases an exclusive mode lock. */
|
|
300 |
#define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
|
|
301 |
||
302 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
303 |
Low-level function which locks an rw-lock in s-mode when we know that it
|
304 |
is possible and none else is currently accessing the rw-lock structure.
|
|
305 |
Then we can do the locking without reserving the mutex. */
|
|
306 |
UNIV_INLINE
|
|
307 |
void
|
|
308 |
rw_lock_s_lock_direct( |
|
309 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
310 |
rw_lock_t* lock, /*!< in/out: rw-lock */ |
311 |
const char* file_name, /*!< in: file name where requested */ |
|
312 |
ulint line); /*!< in: line where lock requested */ |
|
313 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
314 |
Low-level function which locks an rw-lock in x-mode when we know that it
|
315 |
is not locked and none else is currently accessing the rw-lock structure.
|
|
316 |
Then we can do the locking without reserving the mutex. */
|
|
317 |
UNIV_INLINE
|
|
318 |
void
|
|
319 |
rw_lock_x_lock_direct( |
|
320 |
/*==================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
321 |
rw_lock_t* lock, /*!< in/out: rw-lock */ |
322 |
const char* file_name, /*!< in: file name where requested */ |
|
323 |
ulint line); /*!< in: line where lock requested */ |
|
324 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
325 |
This function is used in the insert buffer to move the ownership of an
|
326 |
x-latch on a buffer frame to the current thread. The x-latch was set by
|
|
327 |
the buffer read operation and it protected the buffer frame while the
|
|
328 |
read was done. The ownership is moved because we want that the current
|
|
329 |
thread is able to acquire a second x-latch which is stored in an mtr.
|
|
330 |
This, in turn, is needed to pass the debug checks of index page
|
|
331 |
operations. */
|
|
332 |
UNIV_INTERN
|
|
333 |
void
|
|
334 |
rw_lock_x_lock_move_ownership( |
|
335 |
/*==========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
336 |
rw_lock_t* lock); /*!< in: lock which was x-locked in the |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
337 |
buffer read */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
338 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
339 |
Releases a shared mode lock when we know there are no waiters and none
|
340 |
else will access the lock during the time this function is executed. */
|
|
341 |
UNIV_INLINE
|
|
342 |
void
|
|
343 |
rw_lock_s_unlock_direct( |
|
344 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
345 |
rw_lock_t* lock); /*!< in/out: rw-lock */ |
346 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
347 |
Releases an exclusive mode lock when we know there are no waiters, and
|
348 |
none else will access the lock durint the time this function is executed. */
|
|
349 |
UNIV_INLINE
|
|
350 |
void
|
|
351 |
rw_lock_x_unlock_direct( |
|
352 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
353 |
rw_lock_t* lock); /*!< in/out: rw-lock */ |
354 |
/******************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
355 |
Returns the value of writer_count for the lock. Does not reserve the lock
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
356 |
mutex, so the caller must be sure it is not changed during the call.
|
357 |
@return value of writer_count */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
358 |
UNIV_INLINE
|
359 |
ulint
|
|
360 |
rw_lock_get_x_lock_count( |
|
361 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
362 |
const rw_lock_t* lock); /*!< in: rw-lock */ |
363 |
/********************************************************************//**
|
|
364 |
Check if there are threads waiting for the rw-lock.
|
|
365 |
@return 1 if waiters, 0 otherwise */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
366 |
UNIV_INLINE
|
367 |
ulint
|
|
368 |
rw_lock_get_waiters( |
|
369 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
370 |
const rw_lock_t* lock); /*!< in: rw-lock */ |
371 |
/******************************************************************//**
|
|
372 |
Returns the write-status of the lock - this function made more sense
|
|
373 |
with the old rw_lock implementation.
|
|
374 |
@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
375 |
UNIV_INLINE
|
376 |
ulint
|
|
377 |
rw_lock_get_writer( |
|
378 |
/*===============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
379 |
const rw_lock_t* lock); /*!< in: rw-lock */ |
380 |
/******************************************************************//**
|
|
381 |
Returns the number of readers.
|
|
382 |
@return number of readers */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
383 |
UNIV_INLINE
|
384 |
ulint
|
|
385 |
rw_lock_get_reader_count( |
|
386 |
/*=====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
387 |
const rw_lock_t* lock); /*!< in: rw-lock */ |
388 |
/******************************************************************//**
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
389 |
Decrements lock_word the specified amount if it is greater than 0.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
390 |
This is used by both s_lock and x_lock operations.
|
391 |
@return TRUE if decr occurs */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
392 |
UNIV_INLINE
|
393 |
ibool
|
|
394 |
rw_lock_lock_word_decr( |
|
395 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
396 |
rw_lock_t* lock, /*!< in/out: rw-lock */ |
397 |
ulint amount); /*!< in: amount to decrement */ |
|
398 |
/******************************************************************//**
|
|
399 |
Increments lock_word the specified amount and returns new value.
|
|
400 |
@return lock->lock_word after increment */
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
401 |
UNIV_INLINE
|
402 |
lint
|
|
403 |
rw_lock_lock_word_incr( |
|
404 |
/*===================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
405 |
rw_lock_t* lock, /*!< in/out: rw-lock */ |
406 |
ulint amount); /*!< in: amount to increment */ |
|
407 |
/******************************************************************//**
|
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
408 |
This function sets the lock->writer_thread and lock->recursive fields.
|
409 |
For platforms where we are using atomic builtins instead of lock->mutex
|
|
410 |
it sets the lock->writer_thread field using atomics to ensure memory
|
|
411 |
ordering. Note that it is assumed that the caller of this function
|
|
412 |
effectively owns the lock i.e.: nobody else is allowed to modify
|
|
413 |
lock->writer_thread at this point in time.
|
|
414 |
The protocol is that lock->writer_thread MUST be updated BEFORE the
|
|
415 |
lock->recursive flag is set. */
|
|
416 |
UNIV_INLINE
|
|
417 |
void
|
|
418 |
rw_lock_set_writer_id_and_recursion_flag( |
|
419 |
/*=====================================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
420 |
rw_lock_t* lock, /*!< in/out: lock to work on */ |
421 |
ibool recursive); /*!< in: TRUE if recursion |
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
422 |
allowed */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
423 |
#ifdef UNIV_SYNC_DEBUG
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
424 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
425 |
Checks if the thread has locked the rw-lock in the specified mode, with
|
426 |
the pass value == 0. */
|
|
427 |
UNIV_INTERN
|
|
428 |
ibool
|
|
429 |
rw_lock_own( |
|
430 |
/*========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
431 |
rw_lock_t* lock, /*!< in: rw-lock */ |
432 |
ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED, |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
433 |
RW_LOCK_EX */
|
434 |
#endif /* UNIV_SYNC_DEBUG */ |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
435 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
436 |
Checks if somebody has locked the rw-lock in the specified mode. */
|
437 |
UNIV_INTERN
|
|
438 |
ibool
|
|
439 |
rw_lock_is_locked( |
|
440 |
/*==============*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
441 |
rw_lock_t* lock, /*!< in: rw-lock */ |
442 |
ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED, |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
443 |
RW_LOCK_EX */
|
444 |
#ifdef UNIV_SYNC_DEBUG
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
445 |
/***************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
446 |
Prints debug info of an rw-lock. */
|
447 |
UNIV_INTERN
|
|
448 |
void
|
|
449 |
rw_lock_print( |
|
450 |
/*==========*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
451 |
rw_lock_t* lock); /*!< in: rw-lock */ |
452 |
/***************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
453 |
Prints debug info of currently locked rw-locks. */
|
454 |
UNIV_INTERN
|
|
455 |
void
|
|
456 |
rw_lock_list_print_info( |
|
457 |
/*====================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
458 |
FILE* file); /*!< in: file where to print */ |
459 |
/***************************************************************//**
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
460 |
Returns the number of currently locked rw-locks.
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
461 |
Works only in the debug version.
|
462 |
@return number of locked rw-locks */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
463 |
UNIV_INTERN
|
464 |
ulint
|
|
465 |
rw_lock_n_locked(void); |
|
466 |
/*==================*/
|
|
467 |
||
468 |
/*#####################################################################*/
|
|
469 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
470 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
471 |
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
|
472 |
because the debug mutex is also acquired in sync0arr while holding the OS
|
|
473 |
mutex protecting the sync array, and the ordinary mutex_enter might
|
|
474 |
recursively call routines in sync0arr, leading to a deadlock on the OS
|
|
475 |
mutex. */
|
|
476 |
UNIV_INTERN
|
|
477 |
void
|
|
478 |
rw_lock_debug_mutex_enter(void); |
|
479 |
/*==========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
480 |
/******************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
481 |
Releases the debug mutex. */
|
482 |
UNIV_INTERN
|
|
483 |
void
|
|
484 |
rw_lock_debug_mutex_exit(void); |
|
485 |
/*==========================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
486 |
/*********************************************************************//**
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
487 |
Prints info of a debug struct. */
|
488 |
UNIV_INTERN
|
|
489 |
void
|
|
490 |
rw_lock_debug_print( |
|
491 |
/*================*/
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
492 |
rw_lock_debug_t* info); /*!< in: debug struct */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
493 |
#endif /* UNIV_SYNC_DEBUG */ |
494 |
||
495 |
/* NOTE! The structure appears here only for the compiler to know its size.
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
496 |
Do not use its fields directly! */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
497 |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
498 |
/** The structure used in the spin lock implementation of a read-write
|
499 |
lock. Several threads may have a shared lock simultaneously in this
|
|
500 |
lock, but only one writer may have an exclusive lock, in which case no
|
|
501 |
shared locks are allowed. To prevent starving of a writer blocked by
|
|
502 |
readers, a writer may queue for x-lock by decrementing lock_word: no
|
|
503 |
new readers will be let in while the thread waits for readers to
|
|
504 |
exit. */
|
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
505 |
struct rw_lock_struct { |
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
506 |
volatile lint lock_word; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
507 |
/*!< Holds the state of the lock. */
|
508 |
volatile ulint waiters;/*!< 1: there are waiters */ |
|
509 |
volatile ibool recursive;/*!< Default value FALSE which means the lock |
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
510 |
is non-recursive. The value is typically set
|
511 |
to TRUE making normal rw_locks recursive. In
|
|
512 |
case of asynchronous IO, when a non-zero
|
|
513 |
value of 'pass' is passed then we keep the
|
|
514 |
lock non-recursive.
|
|
515 |
This flag also tells us about the state of
|
|
516 |
writer_thread field. If this flag is set
|
|
517 |
then writer_thread MUST contain the thread
|
|
518 |
id of the current x-holder or wait-x thread.
|
|
519 |
This flag must be reset in x_unlock
|
|
520 |
functions before incrementing the lock_word */
|
|
521 |
volatile os_thread_id_t writer_thread; |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
522 |
/*!< Thread id of writer thread. Is only
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
523 |
guaranteed to have sane and non-stale
|
524 |
value iff recursive flag is set. */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
525 |
os_event_t event; /*!< Used by sync0arr.c for thread queueing */ |
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
526 |
os_event_t wait_ex_event; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
527 |
/*!< Event for next-writer to wait on. A thread
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
528 |
must decrement lock_word before waiting. */
|
529 |
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
530 |
mutex_t mutex; /*!< The mutex protecting rw_lock_struct */ |
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
531 |
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */ |
532 |
||
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
533 |
UT_LIST_NODE_T(rw_lock_t) list; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
534 |
/*!< All allocated rw locks are put into a
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
535 |
list */
|
536 |
#ifdef UNIV_SYNC_DEBUG
|
|
537 |
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list; |
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
538 |
/*!< In the debug version: pointer to the debug
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
539 |
info list of the lock */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
540 |
ulint level; /*!< Level in the global latching order. */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
541 |
#endif /* UNIV_SYNC_DEBUG */ |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
542 |
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */ |
543 |
const char* cfile_name;/*!< File name where lock created */ |
|
641.2.2
by Monty Taylor
InnoDB Plugin 1.0.3 |
544 |
/* last s-lock file/line is not guaranteed to be correct */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
545 |
const char* last_s_file_name;/*!< File name where last s-locked */ |
546 |
const char* last_x_file_name;/*!< File name where last x-locked */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
547 |
ibool writer_is_wait_ex; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
548 |
/*!< This is TRUE if the writer field is
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
549 |
RW_LOCK_WAIT_EX; this field is located far
|
550 |
from the memory update hotspot fields which
|
|
551 |
are at the start of this struct, thus we can
|
|
552 |
peek this field without causing much memory
|
|
553 |
bus traffic */
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
554 |
unsigned cline:14; /*!< Line where created */ |
555 |
unsigned last_s_line:14; /*!< Line number where last time s-locked */ |
|
556 |
unsigned last_x_line:14; /*!< Line number where last time x-locked */ |
|
557 |
ulint magic_n; /*!< RW_LOCK_MAGIC_N */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
558 |
};
|
559 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
560 |
/** Value of rw_lock_struct::magic_n */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
561 |
#define RW_LOCK_MAGIC_N 22643
|
562 |
||
563 |
#ifdef UNIV_SYNC_DEBUG
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
564 |
/** The structure for storing debug info of an rw-lock */
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
565 |
struct rw_lock_debug_struct { |
566 |
||
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
567 |
os_thread_id_t thread_id; /*!< The thread id of the thread which |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
568 |
locked the rw-lock */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
569 |
ulint pass; /*!< Pass value given in the lock operation */ |
570 |
ulint lock_type; /*!< Type of the lock: RW_LOCK_EX, |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
571 |
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
572 |
const char* file_name;/*!< File name where the lock was obtained */ |
573 |
ulint line; /*!< Line where the rw-lock was locked */ |
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
574 |
UT_LIST_NODE_T(rw_lock_debug_t) list; |
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
575 |
/*!< Debug structs are linked in a two-way
|
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
576 |
list */
|
577 |
};
|
|
578 |
#endif /* UNIV_SYNC_DEBUG */ |
|
579 |
||
580 |
#ifndef UNIV_NONINL
|
|
581 |
#include "sync0rw.ic" |
|
582 |
#endif
|
|
641.2.3
by Monty Taylor
InnoDB Plugin 1.0.4 |
583 |
#endif /* !UNIV_HOTBACKUP */ |
641.1.2
by Monty Taylor
Imported 1.0.1 with clean - with no changes. |
584 |
|
585 |
#endif
|