~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/buf0buf.ic

  • Committer: Brian Aker
  • Date: 2009-07-11 19:23:04 UTC
  • mfrom: (1089.1.14 merge)
  • Revision ID: brian@gaz-20090711192304-ootijyl5yf9jq9kd
Merge Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************
2
 
The database buffer buf_pool
3
 
 
4
 
(c) 1995 Innobase Oy
5
 
 
6
 
Created 11/5/1995 Heikki Tuuri
7
 
*******************************************************/
8
 
 
9
 
#include "buf0flu.h"
10
 
#include "buf0lru.h"
11
 
#include "buf0rea.h"
12
 
#include "mtr0mtr.h"
13
 
 
14
 
#ifdef UNIV_DEBUG
15
 
extern ulint            buf_dbg_counter; /* This is used to insert validation
16
 
                                        operations in execution in the
17
 
                                        debug version */
18
 
#endif /* UNIV_DEBUG */
19
 
/************************************************************************
20
 
Recommends a move of a block to the start of the LRU list if there is danger
21
 
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
22
 
mutex. */
23
 
UNIV_INLINE
24
 
ibool
25
 
buf_block_peek_if_too_old(
26
 
/*======================*/
27
 
                                /* out: TRUE if should be made younger */
28
 
        buf_block_t*    block)  /* in: block to make younger */
29
 
{
30
 
        return(buf_pool->freed_page_clock >= block->freed_page_clock
31
 
               + 1 + (buf_pool->curr_size / 4));
32
 
}
33
 
 
34
 
/*************************************************************************
35
 
Gets the current size of buffer buf_pool in bytes. In the case of AWE, the
36
 
size of AWE window (= the frames). */
37
 
UNIV_INLINE
38
 
ulint
39
 
buf_pool_get_curr_size(void)
40
 
/*========================*/
41
 
                        /* out: size in bytes */
42
 
{
43
 
        return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
44
 
}
45
 
 
46
 
/*************************************************************************
47
 
Gets the maximum size of buffer buf_pool in bytes. In the case of AWE, the
48
 
size of AWE window (= the frames). */
49
 
UNIV_INLINE
50
 
ulint
51
 
buf_pool_get_max_size(void)
52
 
/*=======================*/
53
 
                        /* out: size in bytes */
54
 
{
55
 
        return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
56
 
}
57
 
 
58
 
/***********************************************************************
59
 
Accessor function for block array. */
60
 
UNIV_INLINE
61
 
buf_block_t*
62
 
buf_pool_get_nth_block(
63
 
/*===================*/
64
 
                                /* out: pointer to block */
65
 
        buf_pool_t*     buf_pool,/* in: buf_pool */
66
 
        ulint           i)      /* in: index of the block */
67
 
{
68
 
        ut_ad(buf_pool);
69
 
        ut_ad(i < buf_pool->max_size);
70
 
 
71
 
        return(i + buf_pool->blocks);
72
 
}
73
 
 
74
 
/***********************************************************************
75
 
Checks if a pointer points to the block array of the buffer pool (blocks, not
76
 
the frames). */
77
 
UNIV_INLINE
78
 
ibool
79
 
buf_pool_is_block(
80
 
/*==============*/
81
 
                        /* out: TRUE if pointer to block */
82
 
        void*   ptr)    /* in: pointer to memory */
83
 
{
84
 
        if ((buf_pool->blocks <= (buf_block_t*)ptr)
85
 
            && ((buf_block_t*)ptr < buf_pool->blocks
86
 
                + buf_pool->max_size)) {
87
 
 
88
 
                return(TRUE);
89
 
        }
90
 
 
91
 
        return(FALSE);
92
 
}
93
 
 
94
 
/************************************************************************
95
 
Gets the smallest oldest_modification lsn for any page in the pool. Returns
96
 
ut_dulint_zero if all modified pages have been flushed to disk. */
97
 
UNIV_INLINE
98
 
dulint
99
 
buf_pool_get_oldest_modification(void)
100
 
/*==================================*/
101
 
                                /* out: oldest modification in pool,
102
 
                                ut_dulint_zero if none */
103
 
{
104
 
        buf_block_t*    block;
105
 
        dulint          lsn;
106
 
 
107
 
        mutex_enter(&(buf_pool->mutex));
108
 
 
109
 
        block = UT_LIST_GET_LAST(buf_pool->flush_list);
110
 
 
111
 
        if (block == NULL) {
112
 
                lsn = ut_dulint_zero;
113
 
        } else {
114
 
                lsn = block->oldest_modification;
115
 
        }
116
 
 
117
 
        mutex_exit(&(buf_pool->mutex));
118
 
 
119
 
        return(lsn);
120
 
}
121
 
 
122
 
/***********************************************************************
123
 
Increments the buf_pool clock by one and returns its new value. Remember
124
 
that in the 32 bit version the clock wraps around at 4 billion! */
125
 
UNIV_INLINE
126
 
ulint
127
 
buf_pool_clock_tic(void)
128
 
/*====================*/
129
 
                        /* out: new clock value */
130
 
{
131
 
        ut_ad(mutex_own(&(buf_pool->mutex)));
132
 
 
133
 
        buf_pool->ulint_clock++;
134
 
 
135
 
        return(buf_pool->ulint_clock);
136
 
}
137
 
 
138
 
/*************************************************************************
139
 
Gets a pointer to the memory frame of a block. */
140
 
UNIV_INLINE
141
 
buf_frame_t*
142
 
buf_block_get_frame(
143
 
/*================*/
144
 
                                /* out: pointer to the frame */
145
 
        buf_block_t*    block)  /* in: pointer to the control block */
146
 
{
147
 
        ut_ad(block);
148
 
        ut_ad(block >= buf_pool->blocks);
149
 
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
150
 
        ut_ad(block->state != BUF_BLOCK_NOT_USED);
151
 
        ut_ad((block->state != BUF_BLOCK_FILE_PAGE)
152
 
              || (block->buf_fix_count > 0));
153
 
 
154
 
        return(block->frame);
155
 
}
156
 
 
157
 
/*************************************************************************
158
 
Gets the space id of a block. */
159
 
UNIV_INLINE
160
 
ulint
161
 
buf_block_get_space(
162
 
/*================*/
163
 
                                /* out: space id */
164
 
        buf_block_t*    block)  /* in: pointer to the control block */
165
 
{
166
 
        ut_ad(block);
167
 
        ut_ad(block >= buf_pool->blocks);
168
 
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
169
 
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
170
 
        ut_ad(block->buf_fix_count > 0);
171
 
 
172
 
        return(block->space);
173
 
}
174
 
 
175
 
/*************************************************************************
176
 
Gets the page number of a block. */
177
 
UNIV_INLINE
178
 
ulint
179
 
buf_block_get_page_no(
180
 
/*==================*/
181
 
                                /* out: page number */
182
 
        buf_block_t*    block)  /* in: pointer to the control block */
183
 
{
184
 
        ut_ad(block);
185
 
        ut_ad(block >= buf_pool->blocks);
186
 
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
187
 
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
188
 
        ut_ad(block->buf_fix_count > 0);
189
 
 
190
 
        return(block->offset);
191
 
}
192
 
 
193
 
/***********************************************************************
194
 
Gets the block to whose frame the pointer is pointing to. */
195
 
UNIV_INLINE
196
 
buf_block_t*
197
 
buf_block_align(
198
 
/*============*/
199
 
                        /* out: pointer to block */
200
 
        byte*   ptr)    /* in: pointer to a frame */
201
 
{
202
 
        buf_block_t*    block;
203
 
        buf_frame_t*    frame_zero;
204
 
 
205
 
        ut_ad(ptr);
206
 
 
207
 
        frame_zero = buf_pool->frame_zero;
208
 
 
209
 
        if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
210
 
            || UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
211
 
 
212
 
                ut_print_timestamp(stderr);
213
 
                fprintf(stderr,
214
 
                        "InnoDB: Error: trying to access a stray pointer %p\n"
215
 
                        "InnoDB: buf pool start is at %p, end at %p\n"
216
 
                        "InnoDB: Probable reason is database corruption"
217
 
                        " or memory\n"
218
 
                        "InnoDB: corruption. If this happens in an"
219
 
                        " InnoDB database recovery, see\n"
220
 
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
221
 
                        "forcing-recovery.html\n"
222
 
                        "InnoDB: how to force recovery.\n",
223
 
                        ptr, frame_zero,
224
 
                        buf_pool->high_end);
225
 
                ut_error;
226
 
        }
227
 
 
228
 
        block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero))
229
 
                                                >> UNIV_PAGE_SIZE_SHIFT));
230
 
        return(block);
231
 
}
232
 
 
233
 
/***********************************************************************
234
 
Gets the frame the pointer is pointing to. */
235
 
UNIV_INLINE
236
 
buf_frame_t*
237
 
buf_frame_align(
238
 
/*============*/
239
 
                        /* out: pointer to frame */
240
 
        byte*   ptr)    /* in: pointer to a frame */
241
 
{
242
 
        buf_frame_t*    frame;
243
 
 
244
 
        ut_ad(ptr);
245
 
 
246
 
        frame = ut_align_down(ptr, UNIV_PAGE_SIZE);
247
 
 
248
 
        if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
249
 
            || UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
250
 
 
251
 
                ut_print_timestamp(stderr);
252
 
                fprintf(stderr,
253
 
                        "InnoDB: Error: trying to access a stray pointer %p\n"
254
 
                        "InnoDB: buf pool start is at %p, end at %p\n"
255
 
                        "InnoDB: Probable reason is database corruption"
256
 
                        " or memory\n"
257
 
                        "InnoDB: corruption. If this happens in an"
258
 
                        " InnoDB database recovery, see\n"
259
 
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
260
 
                        "forcing-recovery.html\n"
261
 
                        "InnoDB: how to force recovery.\n",
262
 
                        ptr, buf_pool->frame_zero,
263
 
                        buf_pool->high_end);
264
 
                ut_error;
265
 
        }
266
 
 
267
 
        return(frame);
268
 
}
269
 
 
270
 
/**************************************************************************
271
 
Gets the page number of a pointer pointing within a buffer frame containing
272
 
a file page. */
273
 
UNIV_INLINE
274
 
ulint
275
 
buf_frame_get_page_no(
276
 
/*==================*/
277
 
                        /* out: page number */
278
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
279
 
{
280
 
        return(buf_block_get_page_no(buf_block_align(ptr)));
281
 
}
282
 
 
283
 
/**************************************************************************
284
 
Gets the space id of a pointer pointing within a buffer frame containing a
285
 
file page. */
286
 
UNIV_INLINE
287
 
ulint
288
 
buf_frame_get_space_id(
289
 
/*===================*/
290
 
                        /* out: space id */
291
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
292
 
{
293
 
        return(buf_block_get_space(buf_block_align(ptr)));
294
 
}
295
 
 
296
 
/**************************************************************************
297
 
Gets the space id, page offset, and byte offset within page of a
298
 
pointer pointing to a buffer frame containing a file page. */
299
 
UNIV_INLINE
300
 
void
301
 
buf_ptr_get_fsp_addr(
302
 
/*=================*/
303
 
        byte*           ptr,    /* in: pointer to a buffer frame */
304
 
        ulint*          space,  /* out: space id */
305
 
        fil_addr_t*     addr)   /* out: page offset and byte offset */
306
 
{
307
 
        buf_block_t*    block;
308
 
 
309
 
        block = buf_block_align(ptr);
310
 
 
311
 
        *space = buf_block_get_space(block);
312
 
        addr->page = buf_block_get_page_no(block);
313
 
        addr->boffset = ptr - buf_frame_align(ptr);
314
 
}
315
 
 
316
 
/**************************************************************************
317
 
Gets the hash value of the page the pointer is pointing to. This can be used
318
 
in searches in the lock hash table. */
319
 
UNIV_INLINE
320
 
ulint
321
 
buf_frame_get_lock_hash_val(
322
 
/*========================*/
323
 
                        /* out: lock hash value */
324
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
325
 
{
326
 
        buf_block_t*    block;
327
 
 
328
 
        block = buf_block_align(ptr);
329
 
 
330
 
        return(block->lock_hash_val);
331
 
}
332
 
 
333
 
/**************************************************************************
334
 
Gets the mutex number protecting the page record lock hash chain in the lock
335
 
table. */
336
 
UNIV_INLINE
337
 
mutex_t*
338
 
buf_frame_get_mutex(
339
 
/*================*/
340
 
                        /* out: mutex */
341
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
342
 
{
343
 
        buf_block_t*    block;
344
 
 
345
 
        block = buf_block_align(ptr);
346
 
 
347
 
        return(&block->mutex);
348
 
}
349
 
 
350
 
/*************************************************************************
351
 
Copies contents of a buffer frame to a given buffer. */
352
 
UNIV_INLINE
353
 
byte*
354
 
buf_frame_copy(
355
 
/*===========*/
356
 
                                /* out: buf */
357
 
        byte*           buf,    /* in: buffer to copy to */
358
 
        buf_frame_t*    frame)  /* in: buffer frame */
359
 
{
360
 
        ut_ad(buf && frame);
361
 
 
362
 
        ut_memcpy(buf, frame, UNIV_PAGE_SIZE);
363
 
 
364
 
        return(buf);
365
 
}
366
 
 
367
 
/************************************************************************
368
 
Calculates a folded value of a file page address to use in the page hash
369
 
table. */
370
 
UNIV_INLINE
371
 
ulint
372
 
buf_page_address_fold(
373
 
/*==================*/
374
 
                        /* out: the folded value */
375
 
        ulint   space,  /* in: space id */
376
 
        ulint   offset) /* in: offset of the page within space */
377
 
{
378
 
        return((space << 20) + space + offset);
379
 
}
380
 
 
381
 
/************************************************************************
382
 
This function is used to get info if there is an io operation
383
 
going on on a buffer page. */
384
 
UNIV_INLINE
385
 
ibool
386
 
buf_page_io_query(
387
 
/*==============*/
388
 
                                /* out: TRUE if io going on */
389
 
        buf_block_t*    block)  /* in: buf_pool block, must be bufferfixed */
390
 
{
391
 
        mutex_enter(&(buf_pool->mutex));
392
 
 
393
 
        ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
394
 
        ut_ad(block->buf_fix_count > 0);
395
 
 
396
 
        if (block->io_fix != 0) {
397
 
                mutex_exit(&(buf_pool->mutex));
398
 
 
399
 
                return(TRUE);
400
 
        }
401
 
 
402
 
        mutex_exit(&(buf_pool->mutex));
403
 
 
404
 
        return(FALSE);
405
 
}
406
 
 
407
 
/************************************************************************
408
 
Gets the youngest modification log sequence number for a frame. Returns zero
409
 
if not a file page or no modification occurred yet. */
410
 
UNIV_INLINE
411
 
dulint
412
 
buf_frame_get_newest_modification(
413
 
/*==============================*/
414
 
                                /* out: newest modification to the page */
415
 
        buf_frame_t*    frame)  /* in: pointer to a frame */
416
 
{
417
 
        buf_block_t*    block;
418
 
        dulint          lsn;
419
 
 
420
 
        ut_ad(frame);
421
 
 
422
 
        block = buf_block_align(frame);
423
 
 
424
 
        mutex_enter(&(buf_pool->mutex));
425
 
 
426
 
        if (block->state == BUF_BLOCK_FILE_PAGE) {
427
 
                lsn = block->newest_modification;
428
 
        } else {
429
 
                lsn = ut_dulint_zero;
430
 
        }
431
 
 
432
 
        mutex_exit(&(buf_pool->mutex));
433
 
 
434
 
        return(lsn);
435
 
}
436
 
 
437
 
/************************************************************************
438
 
Increments the modify clock of a frame by 1. The caller must (1) own the
439
 
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
440
 
on the block. */
441
 
UNIV_INLINE
442
 
dulint
443
 
buf_frame_modify_clock_inc(
444
 
/*=======================*/
445
 
                                /* out: new value */
446
 
        buf_frame_t*    frame)  /* in: pointer to a frame */
447
 
{
448
 
        buf_block_t*    block;
449
 
 
450
 
        ut_ad(frame);
451
 
 
452
 
        block = buf_block_align(frame);
453
 
 
454
 
#ifdef UNIV_SYNC_DEBUG
455
 
        ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
456
 
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
457
 
#endif /* UNIV_SYNC_DEBUG */
458
 
 
459
 
        UT_DULINT_INC(block->modify_clock);
460
 
 
461
 
        return(block->modify_clock);
462
 
}
463
 
 
464
 
/************************************************************************
465
 
Increments the modify clock of a frame by 1. The caller must (1) own the
466
 
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
467
 
on the block. */
468
 
UNIV_INLINE
469
 
dulint
470
 
buf_block_modify_clock_inc(
471
 
/*=======================*/
472
 
                                /* out: new value */
473
 
        buf_block_t*    block)  /* in: block */
474
 
{
475
 
#ifdef UNIV_SYNC_DEBUG
476
 
        ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
477
 
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
478
 
#endif /* UNIV_SYNC_DEBUG */
479
 
 
480
 
        UT_DULINT_INC(block->modify_clock);
481
 
 
482
 
        return(block->modify_clock);
483
 
}
484
 
 
485
 
/************************************************************************
486
 
Returns the value of the modify clock. The caller must have an s-lock
487
 
or x-lock on the block. */
488
 
UNIV_INLINE
489
 
dulint
490
 
buf_block_get_modify_clock(
491
 
/*=======================*/
492
 
                                /* out: value */
493
 
        buf_block_t*    block)  /* in: block */
494
 
{
495
 
#ifdef UNIV_SYNC_DEBUG
496
 
        ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
497
 
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
498
 
#endif /* UNIV_SYNC_DEBUG */
499
 
 
500
 
        return(block->modify_clock);
501
 
}
502
 
 
503
 
#ifdef UNIV_SYNC_DEBUG
504
 
/***********************************************************************
505
 
Increments the bufferfix count. */
506
 
UNIV_INLINE
507
 
void
508
 
buf_block_buf_fix_inc_debug(
509
 
/*========================*/
510
 
        buf_block_t*    block,  /* in: block to bufferfix */
511
 
        const char*     file __attribute__ ((unused)),  /* in: file name */
512
 
        ulint           line __attribute__ ((unused)))  /* in: line */
513
 
{
514
 
        ibool   ret;
515
 
 
516
 
        ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
517
 
 
518
 
        ut_ad(ret == TRUE);
519
 
        ut_ad(mutex_own(&block->mutex));
520
 
        block->buf_fix_count++;
521
 
}
522
 
#else /* UNIV_SYNC_DEBUG */
523
 
/***********************************************************************
524
 
Increments the bufferfix count. */
525
 
UNIV_INLINE
526
 
void
527
 
buf_block_buf_fix_inc(
528
 
/*==================*/
529
 
        buf_block_t*    block)  /* in: block to bufferfix */
530
 
{
531
 
        ut_ad(mutex_own(&block->mutex));
532
 
 
533
 
        block->buf_fix_count++;
534
 
}
535
 
#endif /* UNIV_SYNC_DEBUG */
536
 
/**********************************************************************
537
 
Returns the control block of a file page, NULL if not found. */
538
 
UNIV_INLINE
539
 
buf_block_t*
540
 
buf_page_hash_get(
541
 
/*==============*/
542
 
                        /* out: block, NULL if not found */
543
 
        ulint   space,  /* in: space id */
544
 
        ulint   offset) /* in: offset of the page within space */
545
 
{
546
 
        buf_block_t*    block;
547
 
        ulint           fold;
548
 
 
549
 
        ut_ad(buf_pool);
550
 
        ut_ad(mutex_own(&(buf_pool->mutex)));
551
 
 
552
 
        /* Look for the page in the hash table */
553
 
 
554
 
        fold = buf_page_address_fold(space, offset);
555
 
 
556
 
        HASH_SEARCH(hash, buf_pool->page_hash, fold, block,
557
 
                    (block->space == space) && (block->offset == offset));
558
 
        ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE);
559
 
 
560
 
        return(block);
561
 
}
562
 
 
563
 
/************************************************************************
564
 
Tries to get the page, but if file io is required, releases all latches
565
 
in mtr down to the given savepoint. If io is required, this function
566
 
retrieves the page to buffer buf_pool, but does not bufferfix it or latch
567
 
it. */
568
 
UNIV_INLINE
569
 
buf_frame_t*
570
 
buf_page_get_release_on_io(
571
 
/*=======================*/
572
 
                                /* out: pointer to the frame, or NULL
573
 
                                if not in buffer buf_pool */
574
 
        ulint   space,          /* in: space id */
575
 
        ulint   offset,         /* in: offset of the page within space
576
 
                                in units of a page */
577
 
        buf_frame_t* guess,     /* in: guessed frame or NULL */
578
 
        ulint   rw_latch,       /* in: RW_X_LATCH, RW_S_LATCH,
579
 
                                or RW_NO_LATCH */
580
 
        ulint   savepoint,      /* in: mtr savepoint */
581
 
        mtr_t*  mtr)            /* in: mtr */
582
 
{
583
 
        buf_frame_t*    frame;
584
 
 
585
 
        frame = buf_page_get_gen(space, offset, rw_latch, guess,
586
 
                                 BUF_GET_IF_IN_POOL,
587
 
                                 __FILE__, __LINE__,
588
 
                                 mtr);
589
 
        if (frame != NULL) {
590
 
 
591
 
                return(frame);
592
 
        }
593
 
 
594
 
        /* The page was not in the buffer buf_pool: release the latches
595
 
        down to the savepoint */
596
 
 
597
 
        mtr_rollback_to_savepoint(mtr, savepoint);
598
 
 
599
 
        buf_page_get(space, offset, RW_S_LATCH, mtr);
600
 
 
601
 
        /* When we get here, the page is in buffer, but we release
602
 
        the latches again down to the savepoint, before returning */
603
 
 
604
 
        mtr_rollback_to_savepoint(mtr, savepoint);
605
 
 
606
 
        return(NULL);
607
 
}
608
 
 
609
 
/************************************************************************
610
 
Decrements the bufferfix count of a buffer control block and releases
611
 
a latch, if specified. */
612
 
UNIV_INLINE
613
 
void
614
 
buf_page_release(
615
 
/*=============*/
616
 
        buf_block_t*    block,          /* in: buffer block */
617
 
        ulint           rw_latch,       /* in: RW_S_LATCH, RW_X_LATCH,
618
 
                                        RW_NO_LATCH */
619
 
        mtr_t*          mtr)            /* in: mtr */
620
 
{
621
 
        ut_ad(block);
622
 
 
623
 
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
624
 
        ut_a(block->buf_fix_count > 0);
625
 
 
626
 
        if (rw_latch == RW_X_LATCH && mtr->modifications) {
627
 
                mutex_enter(&buf_pool->mutex);
628
 
                buf_flush_note_modification(block, mtr);
629
 
                mutex_exit(&buf_pool->mutex);
630
 
        }
631
 
 
632
 
        mutex_enter(&block->mutex);
633
 
 
634
 
#ifdef UNIV_SYNC_DEBUG
635
 
        rw_lock_s_unlock(&(block->debug_latch));
636
 
#endif
637
 
        block->buf_fix_count--;
638
 
 
639
 
        mutex_exit(&block->mutex);
640
 
 
641
 
        if (rw_latch == RW_S_LATCH) {
642
 
                rw_lock_s_unlock(&(block->lock));
643
 
        } else if (rw_latch == RW_X_LATCH) {
644
 
                rw_lock_x_unlock(&(block->lock));
645
 
        }
646
 
}
647
 
 
648
 
#ifdef UNIV_SYNC_DEBUG
649
 
/*************************************************************************
650
 
Adds latch level info for the rw-lock protecting the buffer frame. This
651
 
should be called in the debug version after a successful latching of a
652
 
page if we know the latching order level of the acquired latch. If
653
 
UNIV_SYNC_DEBUG is not defined, compiles to an empty function. */
654
 
UNIV_INLINE
655
 
void
656
 
buf_page_dbg_add_level(
657
 
/*===================*/
658
 
        buf_frame_t*    frame __attribute__((unused)), /* in: buffer page
659
 
                                where we have acquired latch */
660
 
        ulint           level __attribute__((unused))) /* in: latching order
661
 
                                level */
662
 
{
663
 
        sync_thread_add_level(&(buf_block_align(frame)->lock), level);
664
 
}
665
 
#endif /* UNIV_SYNC_DEBUG */