~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/******************************************************
2
Mutex, the basic synchronization primitive
3
4
(c) 1995 Innobase Oy
5
6
Created 9/5/1995 Heikki Tuuri
7
*******************************************************/
8
9
#ifndef sync0sync_h
10
#define sync0sync_h
11
12
#include "univ.i"
13
#include "sync0types.h"
14
#include "ut0lst.h"
15
#include "ut0mem.h"
16
#include "os0thread.h"
17
#include "os0sync.h"
18
#include "sync0arr.h"
19
20
#ifndef UNIV_HOTBACKUP
21
extern my_bool	timed_mutexes;
22
#endif /* UNIV_HOTBACKUP */
23
24
/**********************************************************************
25
Initializes the synchronization data structures. */
26
27
void
28
sync_init(void);
29
/*===========*/
30
/**********************************************************************
31
Frees the resources in synchronization data structures. */
32
33
void
34
sync_close(void);
35
/*===========*/
36
/**********************************************************************
37
Creates, or rather, initializes a mutex object to a specified memory
38
location (which must be appropriately aligned). The mutex is initialized
39
in the reset state. Explicit freeing of the mutex with mutex_free is
40
necessary only if the memory block containing it is freed. */
41
42
#ifdef UNIV_DEBUG
43
# ifdef UNIV_SYNC_DEBUG
44
#  define mutex_create(M, level)					\
45
	mutex_create_func((M), #M, (level), __FILE__, __LINE__)
46
# else
47
#  define mutex_create(M, level)					\
48
	mutex_create_func((M), #M, __FILE__, __LINE__)
49
# endif
50
#else
51
# define mutex_create(M, level)					\
52
	mutex_create_func((M), __FILE__, __LINE__)
53
#endif
54
55
/**********************************************************************
56
Creates, or rather, initializes a mutex object in a specified memory
57
location (which must be appropriately aligned). The mutex is initialized
58
in the reset state. Explicit freeing of the mutex with mutex_free is
59
necessary only if the memory block containing it is freed. */
60
61
void
62
mutex_create_func(
63
/*==============*/
64
	mutex_t*	mutex,		/* in: pointer to memory */
65
#ifdef UNIV_DEBUG
66
	const char*	cmutex_name,	/* in: mutex name */
67
# ifdef UNIV_SYNC_DEBUG
68
	ulint		level,		/* in: level */
69
# endif /* UNIV_SYNC_DEBUG */
70
#endif /* UNIV_DEBUG */
71
	const char*	cfile_name,	/* in: file name where created */
72
	ulint		cline);		/* in: file line where created */
73
/**********************************************************************
74
Calling this function is obligatory only if the memory buffer containing
75
the mutex is freed. Removes a mutex object from the mutex list. The mutex
76
is checked to be in the reset state. */
77
78
#undef mutex_free			/* Fix for MacOS X */
79
void
80
mutex_free(
81
/*=======*/
82
	mutex_t*	mutex);	/* in: mutex */
83
/******************************************************************
84
NOTE! The following macro should be used in mutex locking, not the
85
corresponding function. */
86
87
#define mutex_enter(M)	  mutex_enter_func((M), __FILE__, __LINE__)
88
/**********************************************************************
89
A noninlined function that reserves a mutex. In ha_innodb.cc we have disabled
90
inlining of InnoDB functions, and no inlined functions should be called from
91
there. That is why we need to duplicate the inlined function here. */
92
93
void
94
mutex_enter_noninline(
95
/*==================*/
96
	mutex_t*	mutex);	/* in: mutex */
97
/******************************************************************
98
NOTE! The following macro should be used in mutex locking, not the
99
corresponding function. */
100
101
/* NOTE! currently same as mutex_enter! */
102
103
#define mutex_enter_fast(M)	mutex_enter_func((M), __FILE__, __LINE__)
104
#define mutex_enter_fast_func	mutex_enter_func;
105
/**********************************************************************
106
NOTE! Use the corresponding macro in the header file, not this function
107
directly. Locks a mutex for the current thread. If the mutex is reserved
108
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting
109
for the mutex before suspending the thread. */
110
UNIV_INLINE
111
void
112
mutex_enter_func(
113
/*=============*/
114
	mutex_t*	mutex,		/* in: pointer to mutex */
115
	const char*	file_name,	/* in: file name where locked */
116
	ulint		line);		/* in: line where locked */
117
/******************************************************************
118
NOTE! The following macro should be used in mutex locking, not the
119
corresponding function. */
120
121
#define mutex_enter_nowait(M)	\
122
	mutex_enter_nowait_func((M), __FILE__, __LINE__)
123
/************************************************************************
124
NOTE! Use the corresponding macro in the header file, not this function
125
directly. Tries to lock the mutex for the current thread. If the lock is not
126
acquired immediately, returns with return value 1. */
127
128
ulint
129
mutex_enter_nowait_func(
130
/*====================*/
131
					/* out: 0 if succeed, 1 if not */
132
	mutex_t*	mutex,		/* in: pointer to mutex */
133
	const char*	file_name,	/* in: file name where mutex
134
					requested */
135
	ulint		line);		/* in: line where requested */
136
/**********************************************************************
137
Unlocks a mutex owned by the current thread. */
138
UNIV_INLINE
139
void
140
mutex_exit(
141
/*=======*/
142
	mutex_t*	mutex);	/* in: pointer to mutex */
143
/**********************************************************************
144
Releases a mutex. */
145
146
void
147
mutex_exit_noninline(
148
/*=================*/
149
	mutex_t*	mutex);	/* in: mutex */
150
/**********************************************************************
151
Returns TRUE if no mutex or rw-lock is currently locked.
152
Works only in the debug version. */
153
154
ibool
155
sync_all_freed(void);
156
/*================*/
157
/*#####################################################################
158
FUNCTION PROTOTYPES FOR DEBUGGING */
159
/***********************************************************************
160
Prints wait info of the sync system. */
161
162
void
163
sync_print_wait_info(
164
/*=================*/
165
	FILE*	file);		/* in: file where to print */
166
/***********************************************************************
167
Prints info of the sync system. */
168
169
void
170
sync_print(
171
/*=======*/
172
	FILE*	file);		/* in: file where to print */
173
#ifdef UNIV_DEBUG
174
/**********************************************************************
175
Checks that the mutex has been initialized. */
176
177
ibool
178
mutex_validate(
179
/*===========*/
180
	const mutex_t*	mutex);
181
/**********************************************************************
182
Checks that the current thread owns the mutex. Works only
183
in the debug version. */
184
185
ibool
186
mutex_own(
187
/*======*/
188
				/* out: TRUE if owns */
189
	const mutex_t*	mutex);	/* in: mutex */
190
#endif /* UNIV_DEBUG */
191
#ifdef UNIV_SYNC_DEBUG
192
/**********************************************************************
193
Adds a latch and its level in the thread level array. Allocates the memory
194
for the array if called first time for this OS thread. Makes the checks
195
against other latch levels stored in the array for this thread. */
196
197
void
198
sync_thread_add_level(
199
/*==================*/
200
	void*	latch,	/* in: pointer to a mutex or an rw-lock */
201
	ulint	level);	/* in: level in the latching order; if
202
			SYNC_LEVEL_VARYING, nothing is done */
203
/**********************************************************************
204
Removes a latch from the thread level array if it is found there. */
205
206
ibool
207
sync_thread_reset_level(
208
/*====================*/
209
			/* out: TRUE if found from the array; it is no error
210
			if the latch is not found, as we presently are not
211
			able to determine the level for every latch
212
			reservation the program does */
213
	void*	latch);	/* in: pointer to a mutex or an rw-lock */
214
/**********************************************************************
215
Checks that the level array for the current thread is empty. */
216
217
ibool
218
sync_thread_levels_empty(void);
219
/*==========================*/
220
			/* out: TRUE if empty */
221
/**********************************************************************
222
Checks that the level array for the current thread is empty. */
223
224
ibool
225
sync_thread_levels_empty_gen(
226
/*=========================*/
227
					/* out: TRUE if empty except the
228
					exceptions specified below */
229
	ibool	dict_mutex_allowed);	/* in: TRUE if dictionary mutex is
230
					allowed to be owned by the thread,
231
					also purge_is_running mutex is
232
					allowed */
233
/**********************************************************************
234
Gets the debug information for a reserved mutex. */
235
236
void
237
mutex_get_debug_info(
238
/*=================*/
239
	mutex_t*	mutex,		/* in: mutex */
240
	const char**	file_name,	/* out: file where requested */
241
	ulint*		line,		/* out: line where requested */
242
	os_thread_id_t* thread_id);	/* out: id of the thread which owns
243
					the mutex */
244
/**********************************************************************
245
Counts currently reserved mutexes. Works only in the debug version. */
246
247
ulint
248
mutex_n_reserved(void);
249
/*==================*/
250
#endif /* UNIV_SYNC_DEBUG */
251
/**********************************************************************
252
NOT to be used outside this module except in debugging! Gets the value
253
of the lock word. */
254
UNIV_INLINE
255
ulint
256
mutex_get_lock_word(
257
/*================*/
258
	const mutex_t*	mutex);	/* in: mutex */
259
#ifdef UNIV_SYNC_DEBUG
260
/**********************************************************************
261
NOT to be used outside this module except in debugging! Gets the waiters
262
field in a mutex. */
263
UNIV_INLINE
264
ulint
265
mutex_get_waiters(
266
/*==============*/
267
				/* out: value to set */
268
	const mutex_t*	mutex);	/* in: mutex */
269
#endif /* UNIV_SYNC_DEBUG */
270
271
/*
272
		LATCHING ORDER WITHIN THE DATABASE
273
		==================================
274
275
The mutex or latch in the central memory object, for instance, a rollback
276
segment object, must be acquired before acquiring the latch or latches to
277
the corresponding file data structure. In the latching order below, these
278
file page object latches are placed immediately below the corresponding
279
central memory object latch or mutex.
280
281
Synchronization object			Notes
282
----------------------			-----
283
284
Dictionary mutex			If we have a pointer to a dictionary
285
|					object, e.g., a table, it can be
286
|					accessed without reserving the
287
|					dictionary mutex. We must have a
288
|					reservation, a memoryfix, to the
289
|					appropriate table object in this case,
290
|					and the table must be explicitly
291
|					released later.
292
V
293
Dictionary header
294
|
295
V
296
Secondary index tree latch		The tree latch protects also all
297
|					the B-tree non-leaf pages. These
298
V					can be read with the page only
299
Secondary index non-leaf		bufferfixed to save CPU time,
300
|					no s-latch is needed on the page.
301
|					Modification of a page requires an
302
|					x-latch on the page, however. If a
303
|					thread owns an x-latch to the tree,
304
|					it is allowed to latch non-leaf pages
305
|					even after it has acquired the fsp
306
|					latch.
307
V
308
Secondary index leaf			The latch on the secondary index leaf
309
|					can be kept while accessing the
310
|					clustered index, to save CPU time.
311
V
312
Clustered index tree latch		To increase concurrency, the tree
313
|					latch is usually released when the
314
|					leaf page latch has been acquired.
315
V
316
Clustered index non-leaf
317
|
318
V
319
Clustered index leaf
320
|
321
V
322
Transaction system header
323
|
324
V
325
Transaction undo mutex			The undo log entry must be written
326
|					before any index page is modified.
327
|					Transaction undo mutex is for the undo
328
|					logs the analogue of the tree latch
329
|					for a B-tree. If a thread has the
330
|					trx undo mutex reserved, it is allowed
331
|					to latch the undo log pages in any
332
|					order, and also after it has acquired
333
|					the fsp latch.
334
V
335
Rollback segment mutex			The rollback segment mutex must be
336
|					reserved, if, e.g., a new page must
337
|					be added to an undo log. The rollback
338
|					segment and the undo logs in its
339
|					history list can be seen as an
340
|					analogue of a B-tree, and the latches
341
|					reserved similarly, using a version of
342
|					lock-coupling. If an undo log must be
343
|					extended by a page when inserting an
344
|					undo log record, this corresponds to
345
|					a pessimistic insert in a B-tree.
346
V
347
Rollback segment header
348
|
349
V
350
Purge system latch
351
|
352
V
353
Undo log pages				If a thread owns the trx undo mutex,
354
|					or for a log in the history list, the
355
|					rseg mutex, it is allowed to latch
356
|					undo log pages in any order, and even
357
|					after it has acquired the fsp latch.
358
|					If a thread does not have the
359
|					appropriate mutex, it is allowed to
360
|					latch only a single undo log page in
361
|					a mini-transaction.
362
V
363
File space management latch		If a mini-transaction must allocate
364
|					several file pages, it can do that,
365
|					because it keeps the x-latch to the
366
|					file space management in its memo.
367
V
368
File system pages
369
|
370
V
371
Kernel mutex				If a kernel operation needs a file
372
|					page allocation, it must reserve the
373
|					fsp x-latch before acquiring the kernel
374
|					mutex.
375
V
376
Search system mutex
377
|
378
V
379
Buffer pool mutex
380
|
381
V
382
Log mutex
383
|
384
Any other latch
385
|
386
V
387
Memory pool mutex */
388
389
/* Latching order levels */
390
391
/* User transaction locks are higher than any of the latch levels below:
392
no latches are allowed when a thread goes to wait for a normal table
393
or row lock! */
394
#define SYNC_USER_TRX_LOCK	9999
395
#define SYNC_NO_ORDER_CHECK	3000	/* this can be used to suppress
396
					latching order checking */
397
#define	SYNC_LEVEL_VARYING	2000	/* Level is varying. Only used with
398
					buffer pool page locks, which do not
399
					have a fixed level, but instead have
400
					their level set after the page is
401
					locked; see e.g.
402
					ibuf_bitmap_get_map_page(). */
403
#define	SYNC_DICT_OPERATION	1001	/* table create, drop, etc. reserve
404
					this in X-mode, implicit or backround
405
					operations purge, rollback, foreign
406
					key checks reserve this in S-mode */
407
#define SYNC_DICT		1000
408
#define SYNC_DICT_AUTOINC_MUTEX	999
409
#define SYNC_DICT_HEADER	995
410
#define SYNC_IBUF_HEADER	914
411
#define SYNC_IBUF_PESS_INSERT_MUTEX 912
412
#define SYNC_IBUF_MUTEX		910	/* ibuf mutex is really below
413
					SYNC_FSP_PAGE: we assign a value this
414
					high only to make the program to pass
415
					the debug checks */
416
/*-------------------------------*/
417
#define	SYNC_INDEX_TREE		900
418
#define SYNC_TREE_NODE_NEW	892
419
#define SYNC_TREE_NODE_FROM_HASH 891
420
#define SYNC_TREE_NODE		890
421
#define	SYNC_PURGE_SYS		810
422
#define	SYNC_PURGE_LATCH	800
423
#define	SYNC_TRX_UNDO		700
424
#define SYNC_RSEG		600
425
#define SYNC_RSEG_HEADER_NEW	591
426
#define SYNC_RSEG_HEADER	590
427
#define SYNC_TRX_UNDO_PAGE	570
428
#define SYNC_EXTERN_STORAGE	500
429
#define	SYNC_FSP		400
430
#define	SYNC_FSP_PAGE		395
431
/*------------------------------------- Insert buffer headers */
432
/*------------------------------------- ibuf_mutex */
433
/*------------------------------------- Insert buffer tree */
434
#define	SYNC_IBUF_BITMAP_MUTEX	351
435
#define	SYNC_IBUF_BITMAP	350
436
/*------------------------------------- MySQL query cache mutex */
437
/*------------------------------------- MySQL binlog mutex */
438
/*-------------------------------*/
439
#define	SYNC_KERNEL		300
440
#define SYNC_REC_LOCK		299
441
#define	SYNC_TRX_LOCK_HEAP	298
442
#define SYNC_TRX_SYS_HEADER	290
443
#define SYNC_LOG		170
444
#define SYNC_RECV		168
445
#define SYNC_WORK_QUEUE		161
446
#define	SYNC_SEARCH_SYS		160	/* NOTE that if we have a memory
447
					heap that can be extended to the
448
					buffer pool, its logical level is
449
					SYNC_SEARCH_SYS, as memory allocation
450
					can call routines there! Otherwise
451
					the level is SYNC_MEM_HASH. */
452
#define	SYNC_BUF_POOL		150
453
#define	SYNC_BUF_BLOCK		149
454
#define SYNC_DOUBLEWRITE	140
455
#define	SYNC_ANY_LATCH		135
456
#define SYNC_THR_LOCAL		133
457
#define	SYNC_MEM_HASH		131
458
#define	SYNC_MEM_POOL		130
459
460
/* Codes used to designate lock operations */
461
#define RW_LOCK_NOT_LOCKED	350
462
#define RW_LOCK_EX		351
463
#define RW_LOCK_EXCLUSIVE	351
464
#define RW_LOCK_SHARED		352
465
#define RW_LOCK_WAIT_EX		353
466
#define SYNC_MUTEX		354
467
468
/* NOTE! The structure appears here only for the compiler to know its size.
469
Do not use its fields directly! The structure used in the spin lock
470
implementation of a mutual exclusion semaphore. */
471
472
struct mutex_struct {
473
	ulint	lock_word;	/* This ulint is the target of the atomic
474
				test-and-set instruction in Win32 */
475
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
476
	os_fast_mutex_t
477
		os_fast_mutex;	/* In other systems we use this OS mutex
478
				in place of lock_word */
479
#endif
480
	ulint	waiters;	/* This ulint is set to 1 if there are (or
481
				may be) threads waiting in the global wait
482
				array for this mutex to be released.
483
				Otherwise, this is 0. */
484
	UT_LIST_NODE_T(mutex_t)	list; /* All allocated mutexes are put into
485
				a list.	Pointers to the next and prev. */
486
#ifdef UNIV_SYNC_DEBUG
487
	const char*	file_name;	/* File where the mutex was locked */
488
	ulint	line;		/* Line where the mutex was locked */
489
	ulint	level;		/* Level in the global latching order */
490
#endif /* UNIV_SYNC_DEBUG */
491
	const char*	cfile_name;/* File name where mutex created */
492
	ulint		cline;	/* Line where created */
493
#ifdef UNIV_DEBUG
494
	os_thread_id_t thread_id; /* The thread id of the thread
495
				which locked the mutex. */
496
	ulint		magic_n;
497
# define MUTEX_MAGIC_N	(ulint)979585
498
#endif /* UNIV_DEBUG */
499
#ifndef UNIV_HOTBACKUP
500
	ulong		count_os_wait; /* count of os_wait */
501
# ifdef UNIV_DEBUG
502
	ulong		count_using; /* count of times mutex used */
503
	ulong		count_spin_loop; /* count of spin loops */
504
	ulong		count_spin_rounds; /* count of spin rounds */
505
	ulong		count_os_yield; /* count of os_wait */
506
	ulonglong	lspent_time; /* mutex os_wait timer msec */
507
	ulonglong	lmax_spent_time; /* mutex os_wait timer msec */
508
	const char*	cmutex_name;/* mutex name */
509
	ulint		mutex_type;/* 0 - usual mutex 1 - rw_lock mutex	 */
510
# endif /* UNIV_DEBUG */
511
#endif /* !UNIV_HOTBACKUP */
512
};
513
514
/* The global array of wait cells for implementation of the databases own
515
mutexes and read-write locks. Appears here for debugging purposes only! */
516
517
extern sync_array_t*	sync_primary_wait_array;
518
519
/* Constant determining how long spin wait is continued before suspending
520
the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond
521
to 20 microseconds. */
522
523
#define	SYNC_SPIN_ROUNDS	srv_n_spin_wait_rounds
524
525
/* The number of system calls made in this module. Intended for performance
526
monitoring. */
527
528
extern	ulint	mutex_system_call_count;
529
extern	ulint	mutex_exit_count;
530
531
#ifdef UNIV_SYNC_DEBUG
532
/* Latching order checks start when this is set TRUE */
533
extern ibool	sync_order_checks_on;
534
#endif /* UNIV_SYNC_DEBUG */
535
536
/* This variable is set to TRUE when sync_init is called */
537
extern ibool	sync_initialized;
538
539
/* Global list of database mutexes (not OS mutexes) created. */
540
typedef UT_LIST_BASE_NODE_T(mutex_t)  ut_list_base_node_t;
541
extern ut_list_base_node_t  mutex_list;
542
543
/* Mutex protecting the mutex_list variable */
544
extern mutex_t mutex_list_mutex;
545
546
547
#ifndef UNIV_NONINL
548
#include "sync0sync.ic"
549
#endif
550
551
#endif