~drizzle-trunk/drizzle/development

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