~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-10-28 08:36:02 UTC
  • mfrom: (520.4.13 merge-innodb-plugin)
  • Revision ID: brian@tangent.org-20081028083602-0p3zzlhlxr5q2sqo
Merging Monty's work

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include "buf0rea.h"
12
12
#include "mtr0mtr.h"
13
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 */
 
14
/************************************************************************
 
15
Reads the freed_page_clock of a buffer block. */
 
16
UNIV_INLINE
 
17
ulint
 
18
buf_page_get_freed_page_clock(
 
19
/*==========================*/
 
20
                                        /* out: freed_page_clock */
 
21
        const buf_page_t*       bpage)  /* in: block */
 
22
{
 
23
        return(bpage->freed_page_clock);
 
24
}
 
25
 
 
26
/************************************************************************
 
27
Reads the freed_page_clock of a buffer block. */
 
28
UNIV_INLINE
 
29
ulint
 
30
buf_block_get_freed_page_clock(
 
31
/*===========================*/
 
32
                                        /* out: freed_page_clock */
 
33
        const buf_block_t*      block)  /* in: block */
 
34
{
 
35
        return(buf_page_get_freed_page_clock(&block->page));
 
36
}
 
37
 
19
38
/************************************************************************
20
39
Recommends a move of a block to the start of the LRU list if there is danger
21
40
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
22
41
mutex. */
23
42
UNIV_INLINE
24
43
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 */
 
44
buf_page_peek_if_too_old(
 
45
/*=====================*/
 
46
                                        /* out: TRUE if should be made
 
47
                                        younger */
 
48
        const buf_page_t*       bpage)  /* in: block to make younger */
29
49
{
30
 
        return(buf_pool->freed_page_clock >= block->freed_page_clock
 
50
        return(buf_pool->freed_page_clock
 
51
               >= buf_page_get_freed_page_clock(bpage)
31
52
               + 1 + (buf_pool->curr_size / 4));
32
53
}
33
54
 
34
55
/*************************************************************************
35
 
Gets the current size of buffer buf_pool in bytes. In the case of AWE, the
36
 
size of AWE window (= the frames). */
 
56
Gets the current size of buffer buf_pool in bytes. */
37
57
UNIV_INLINE
38
58
ulint
39
59
buf_pool_get_curr_size(void)
40
60
/*========================*/
41
61
                        /* out: size in bytes */
42
62
{
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);
 
63
        return(buf_pool->curr_size * UNIV_PAGE_SIZE);
92
64
}
93
65
 
94
66
/************************************************************************
95
67
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. */
 
68
zero if all modified pages have been flushed to disk. */
97
69
UNIV_INLINE
98
 
dulint
 
70
ib_uint64_t
99
71
buf_pool_get_oldest_modification(void)
100
72
/*==================================*/
101
73
                                /* out: oldest modification in pool,
102
 
                                ut_dulint_zero if none */
 
74
                                zero if none */
103
75
{
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;
 
76
        buf_page_t*     bpage;
 
77
        ib_uint64_t     lsn;
 
78
 
 
79
        buf_pool_mutex_enter();
 
80
 
 
81
        bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
 
82
 
 
83
        if (bpage == NULL) {
 
84
                lsn = 0;
113
85
        } else {
114
 
                lsn = block->oldest_modification;
 
86
                ut_ad(bpage->in_flush_list);
 
87
                lsn = bpage->oldest_modification;
115
88
        }
116
89
 
117
 
        mutex_exit(&(buf_pool->mutex));
 
90
        buf_pool_mutex_exit();
118
91
 
119
92
        return(lsn);
120
93
}
128
101
/*====================*/
129
102
                        /* out: new clock value */
130
103
{
131
 
        ut_ad(mutex_own(&(buf_pool->mutex)));
 
104
        ut_ad(buf_pool_mutex_own());
132
105
 
133
106
        buf_pool->ulint_clock++;
134
107
 
136
109
}
137
110
 
138
111
/*************************************************************************
 
112
Gets the state of a block. */
 
113
UNIV_INLINE
 
114
enum buf_page_state
 
115
buf_page_get_state(
 
116
/*===============*/
 
117
                                        /* out: state */
 
118
        const buf_page_t*       bpage)  /* in: pointer to the control block */
 
119
{
 
120
        enum buf_page_state     state = (enum buf_page_state) bpage->state;
 
121
 
 
122
#ifdef UNIV_DEBUG
 
123
        switch (state) {
 
124
        case BUF_BLOCK_ZIP_FREE:
 
125
        case BUF_BLOCK_ZIP_PAGE:
 
126
        case BUF_BLOCK_ZIP_DIRTY:
 
127
        case BUF_BLOCK_NOT_USED:
 
128
        case BUF_BLOCK_READY_FOR_USE:
 
129
        case BUF_BLOCK_FILE_PAGE:
 
130
        case BUF_BLOCK_MEMORY:
 
131
        case BUF_BLOCK_REMOVE_HASH:
 
132
                break;
 
133
        default:
 
134
                ut_error;
 
135
        }
 
136
#endif /* UNIV_DEBUG */
 
137
 
 
138
        return(state);
 
139
}
 
140
/*************************************************************************
 
141
Gets the state of a block. */
 
142
UNIV_INLINE
 
143
enum buf_page_state
 
144
buf_block_get_state(
 
145
/*================*/
 
146
                                        /* out: state */
 
147
        const buf_block_t*      block)  /* in: pointer to the control block */
 
148
{
 
149
        return(buf_page_get_state(&block->page));
 
150
}
 
151
/*************************************************************************
 
152
Sets the state of a block. */
 
153
UNIV_INLINE
 
154
void
 
155
buf_page_set_state(
 
156
/*===============*/
 
157
        buf_page_t*             bpage,  /* in/out: pointer to control block */
 
158
        enum buf_page_state     state)  /* in: state */
 
159
{
 
160
#ifdef UNIV_DEBUG
 
161
        enum buf_page_state     old_state       = buf_page_get_state(bpage);
 
162
 
 
163
        switch (old_state) {
 
164
        case BUF_BLOCK_ZIP_FREE:
 
165
                ut_error;
 
166
                break;
 
167
        case BUF_BLOCK_ZIP_PAGE:
 
168
                ut_a(state == BUF_BLOCK_ZIP_DIRTY);
 
169
                break;
 
170
        case BUF_BLOCK_ZIP_DIRTY:
 
171
                ut_a(state == BUF_BLOCK_ZIP_PAGE);
 
172
                break;
 
173
        case BUF_BLOCK_NOT_USED:
 
174
                ut_a(state == BUF_BLOCK_READY_FOR_USE);
 
175
                break;
 
176
        case BUF_BLOCK_READY_FOR_USE:
 
177
                ut_a(state == BUF_BLOCK_MEMORY
 
178
                     || state == BUF_BLOCK_FILE_PAGE
 
179
                     || state == BUF_BLOCK_NOT_USED);
 
180
                break;
 
181
        case BUF_BLOCK_MEMORY:
 
182
                ut_a(state == BUF_BLOCK_NOT_USED);
 
183
                break;
 
184
        case BUF_BLOCK_FILE_PAGE:
 
185
                ut_a(state == BUF_BLOCK_NOT_USED
 
186
                     || state == BUF_BLOCK_REMOVE_HASH);
 
187
                break;
 
188
        case BUF_BLOCK_REMOVE_HASH:
 
189
                ut_a(state == BUF_BLOCK_MEMORY);
 
190
                break;
 
191
        }
 
192
#endif /* UNIV_DEBUG */
 
193
        bpage->state = state;
 
194
        ut_ad(buf_page_get_state(bpage) == state);
 
195
}
 
196
 
 
197
/*************************************************************************
 
198
Sets the state of a block. */
 
199
UNIV_INLINE
 
200
void
 
201
buf_block_set_state(
 
202
/*================*/
 
203
        buf_block_t*            block,  /* in/out: pointer to control block */
 
204
        enum buf_page_state     state)  /* in: state */
 
205
{
 
206
        buf_page_set_state(&block->page, state);
 
207
}
 
208
 
 
209
/*************************************************************************
 
210
Determines if a block is mapped to a tablespace. */
 
211
UNIV_INLINE
 
212
ibool
 
213
buf_page_in_file(
 
214
/*=============*/
 
215
                                        /* out: TRUE if mapped */
 
216
        const buf_page_t*       bpage)  /* in: pointer to control block */
 
217
{
 
218
        switch (buf_page_get_state(bpage)) {
 
219
        case BUF_BLOCK_ZIP_FREE:
 
220
                /* This is a free page in buf_pool->zip_free[].
 
221
                Such pages should only be accessed by the buddy allocator. */
 
222
                ut_error;
 
223
                break;
 
224
        case BUF_BLOCK_ZIP_PAGE:
 
225
        case BUF_BLOCK_ZIP_DIRTY:
 
226
        case BUF_BLOCK_FILE_PAGE:
 
227
                return(TRUE);
 
228
        case BUF_BLOCK_NOT_USED:
 
229
        case BUF_BLOCK_READY_FOR_USE:
 
230
        case BUF_BLOCK_MEMORY:
 
231
        case BUF_BLOCK_REMOVE_HASH:
 
232
                break;
 
233
        }
 
234
 
 
235
        return(FALSE);
 
236
}
 
237
 
 
238
/*************************************************************************
 
239
Determines if a block should be on unzip_LRU list. */
 
240
UNIV_INLINE
 
241
ibool
 
242
buf_page_belongs_to_unzip_LRU(
 
243
/*==========================*/
 
244
                                        /* out: TRUE if block belongs
 
245
                                        to unzip_LRU */
 
246
        const buf_page_t*       bpage)  /* in: pointer to control block */
 
247
{
 
248
        ut_ad(buf_page_in_file(bpage));
 
249
 
 
250
        return(bpage->zip.data
 
251
               && buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
 
252
}
 
253
 
 
254
/*************************************************************************
 
255
Determine the approximate LRU list position of a block. */
 
256
UNIV_INLINE
 
257
ulint
 
258
buf_page_get_LRU_position(
 
259
/*======================*/
 
260
                                        /* out: LRU list position */
 
261
        const buf_page_t*       bpage)  /* in: control block */
 
262
{
 
263
        ut_ad(buf_page_in_file(bpage));
 
264
 
 
265
        return(bpage->LRU_position);
 
266
}
 
267
 
 
268
/*************************************************************************
 
269
Gets the mutex of a block. */
 
270
UNIV_INLINE
 
271
mutex_t*
 
272
buf_page_get_mutex(
 
273
/*===============*/
 
274
                                        /* out: pointer to mutex
 
275
                                        protecting bpage */
 
276
        const buf_page_t*       bpage)  /* in: pointer to control block */
 
277
{
 
278
        switch (buf_page_get_state(bpage)) {
 
279
        case BUF_BLOCK_ZIP_FREE:
 
280
                ut_error;
 
281
                return(NULL);
 
282
        case BUF_BLOCK_ZIP_PAGE:
 
283
        case BUF_BLOCK_ZIP_DIRTY:
 
284
                return(&buf_pool_zip_mutex);
 
285
        default:
 
286
                return(&((buf_block_t*) bpage)->mutex);
 
287
        }
 
288
}
 
289
 
 
290
/*************************************************************************
 
291
Get the flush type of a page. */
 
292
UNIV_INLINE
 
293
enum buf_flush
 
294
buf_page_get_flush_type(
 
295
/*====================*/
 
296
                                        /* out: flush type */
 
297
        const buf_page_t*       bpage)  /* in: buffer page */
 
298
{
 
299
        enum buf_flush  flush_type = (enum buf_flush) bpage->flush_type;
 
300
 
 
301
#ifdef UNIV_DEBUG
 
302
        switch (flush_type) {
 
303
        case BUF_FLUSH_LRU:
 
304
        case BUF_FLUSH_SINGLE_PAGE:
 
305
        case BUF_FLUSH_LIST:
 
306
                return(flush_type);
 
307
        case BUF_FLUSH_N_TYPES:
 
308
                break;
 
309
        }
 
310
        ut_error;
 
311
#endif /* UNIV_DEBUG */
 
312
        return(flush_type);
 
313
}
 
314
/*************************************************************************
 
315
Set the flush type of a page. */
 
316
UNIV_INLINE
 
317
void
 
318
buf_page_set_flush_type(
 
319
/*====================*/
 
320
        buf_page_t*     bpage,          /* in: buffer page */
 
321
        enum buf_flush  flush_type)     /* in: flush type */
 
322
{
 
323
        bpage->flush_type = flush_type;
 
324
        ut_ad(buf_page_get_flush_type(bpage) == flush_type);
 
325
}
 
326
 
 
327
/*************************************************************************
 
328
Map a block to a file page. */
 
329
UNIV_INLINE
 
330
void
 
331
buf_block_set_file_page(
 
332
/*====================*/
 
333
        buf_block_t*            block,  /* in/out: pointer to control block */
 
334
        ulint                   space,  /* in: tablespace id */
 
335
        ulint                   page_no)/* in: page number */
 
336
{
 
337
        buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
 
338
        block->page.space = space;
 
339
        block->page.offset = page_no;
 
340
}
 
341
 
 
342
/*************************************************************************
 
343
Gets the io_fix state of a block. */
 
344
UNIV_INLINE
 
345
enum buf_io_fix
 
346
buf_page_get_io_fix(
 
347
/*================*/
 
348
                                        /* out: io_fix state */
 
349
        const buf_page_t*       bpage)  /* in: pointer to the control block */
 
350
{
 
351
        enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
 
352
#ifdef UNIV_DEBUG
 
353
        switch (io_fix) {
 
354
        case BUF_IO_NONE:
 
355
        case BUF_IO_READ:
 
356
        case BUF_IO_WRITE:
 
357
                return(io_fix);
 
358
        }
 
359
        ut_error;
 
360
#endif /* UNIV_DEBUG */
 
361
        return(io_fix);
 
362
}
 
363
 
 
364
/*************************************************************************
 
365
Gets the io_fix state of a block. */
 
366
UNIV_INLINE
 
367
enum buf_io_fix
 
368
buf_block_get_io_fix(
 
369
/*================*/
 
370
                                        /* out: io_fix state */
 
371
        const buf_block_t*      block)  /* in: pointer to the control block */
 
372
{
 
373
        return(buf_page_get_io_fix(&block->page));
 
374
}
 
375
 
 
376
/*************************************************************************
 
377
Sets the io_fix state of a block. */
 
378
UNIV_INLINE
 
379
void
 
380
buf_page_set_io_fix(
 
381
/*================*/
 
382
        buf_page_t*     bpage,  /* in/out: control block */
 
383
        enum buf_io_fix io_fix) /* in: io_fix state */
 
384
{
 
385
        ut_ad(buf_pool_mutex_own());
 
386
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
 
387
 
 
388
        bpage->io_fix = io_fix;
 
389
        ut_ad(buf_page_get_io_fix(bpage) == io_fix);
 
390
}
 
391
 
 
392
/*************************************************************************
 
393
Sets the io_fix state of a block. */
 
394
UNIV_INLINE
 
395
void
 
396
buf_block_set_io_fix(
 
397
/*=================*/
 
398
        buf_block_t*    block,  /* in/out: control block */
 
399
        enum buf_io_fix io_fix) /* in: io_fix state */
 
400
{
 
401
        buf_page_set_io_fix(&block->page, io_fix);
 
402
}
 
403
 
 
404
/************************************************************************
 
405
Determine if a buffer block can be relocated in memory.  The block
 
406
can be dirty, but it must not be I/O-fixed or bufferfixed. */
 
407
UNIV_INLINE
 
408
ibool
 
409
buf_page_can_relocate(
 
410
/*==================*/
 
411
        const buf_page_t*       bpage)  /* control block being relocated */
 
412
{
 
413
        ut_ad(buf_pool_mutex_own());
 
414
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
 
415
        ut_ad(buf_page_in_file(bpage));
 
416
        ut_ad(bpage->in_LRU_list);
 
417
 
 
418
        return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
 
419
               && bpage->buf_fix_count == 0);
 
420
}
 
421
 
 
422
/*************************************************************************
 
423
Determine if a block has been flagged old. */
 
424
UNIV_INLINE
 
425
ibool
 
426
buf_page_is_old(
 
427
/*============*/
 
428
                                        /* out: TRUE if old */
 
429
        const buf_page_t*       bpage)  /* in: control block */
 
430
{
 
431
        ut_ad(buf_page_in_file(bpage));
 
432
 
 
433
        return(bpage->old);
 
434
}
 
435
 
 
436
/*************************************************************************
 
437
Flag a block old. */
 
438
UNIV_INLINE
 
439
void
 
440
buf_page_set_old(
 
441
/*=============*/
 
442
        buf_page_t*     bpage,  /* in/out: control block */
 
443
        ibool           old)    /* in: old */
 
444
{
 
445
        ut_a(buf_page_in_file(bpage));
 
446
        ut_ad(buf_pool_mutex_own());
 
447
 
 
448
        bpage->old = old;
 
449
}
 
450
 
 
451
/*************************************************************************
 
452
Determine if a block has been accessed in the buffer pool. */
 
453
UNIV_INLINE
 
454
ibool
 
455
buf_page_is_accessed(
 
456
/*=================*/
 
457
                                        /* out: TRUE if accessed */
 
458
        const buf_page_t*       bpage)  /* in: control block */
 
459
{
 
460
        ut_ad(buf_page_in_file(bpage));
 
461
 
 
462
        return(bpage->accessed);
 
463
}
 
464
 
 
465
/*************************************************************************
 
466
Flag a block accessed. */
 
467
UNIV_INLINE
 
468
void
 
469
buf_page_set_accessed(
 
470
/*==================*/
 
471
        buf_page_t*     bpage,          /* in/out: control block */
 
472
        ibool           accessed)       /* in: accessed */
 
473
{
 
474
        ut_a(buf_page_in_file(bpage));
 
475
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
 
476
 
 
477
        bpage->accessed = accessed;
 
478
}
 
479
 
 
480
/*************************************************************************
 
481
Gets the buf_block_t handle of a buffered file block if an uncompressed
 
482
page frame exists, or NULL. */
 
483
UNIV_INLINE
 
484
buf_block_t*
 
485
buf_page_get_block(
 
486
/*===============*/
 
487
                                /* out: control block, or NULL */
 
488
        buf_page_t*     bpage)  /* in: control block, or NULL */
 
489
{
 
490
        if (UNIV_LIKELY(bpage != NULL)) {
 
491
                ut_ad(buf_page_in_file(bpage));
 
492
 
 
493
                if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
 
494
                        return((buf_block_t*) bpage);
 
495
                }
 
496
        }
 
497
 
 
498
        return(NULL);
 
499
}
 
500
 
 
501
#ifdef UNIV_DEBUG
 
502
/*************************************************************************
139
503
Gets a pointer to the memory frame of a block. */
140
504
UNIV_INLINE
141
505
buf_frame_t*
142
506
buf_block_get_frame(
143
507
/*================*/
144
 
                                /* out: pointer to the frame */
145
 
        buf_block_t*    block)  /* in: pointer to the control block */
 
508
                                        /* out: pointer to the frame */
 
509
        const buf_block_t*      block)  /* in: pointer to the control block */
146
510
{
147
511
        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);
 
512
 
 
513
        switch (buf_block_get_state(block)) {
 
514
        case BUF_BLOCK_ZIP_FREE:
 
515
        case BUF_BLOCK_ZIP_PAGE:
 
516
        case BUF_BLOCK_ZIP_DIRTY:
 
517
        case BUF_BLOCK_NOT_USED:
 
518
                ut_error;
 
519
                break;
 
520
        case BUF_BLOCK_FILE_PAGE:
 
521
                ut_a(block->page.buf_fix_count > 0);
 
522
                /* fall through */
 
523
        case BUF_BLOCK_READY_FOR_USE:
 
524
        case BUF_BLOCK_MEMORY:
 
525
        case BUF_BLOCK_REMOVE_HASH:
 
526
                goto ok;
 
527
        }
 
528
        ut_error;
 
529
ok:
 
530
        return((buf_frame_t*) block->frame);
 
531
}
 
532
#endif /* UNIV_DEBUG */
 
533
 
 
534
/*************************************************************************
 
535
Gets the space id of a block. */
 
536
UNIV_INLINE
 
537
ulint
 
538
buf_page_get_space(
 
539
/*===============*/
 
540
                                        /* out: space id */
 
541
        const buf_page_t*       bpage)  /* in: pointer to the control block */
 
542
{
 
543
        ut_ad(bpage);
 
544
        ut_a(buf_page_in_file(bpage));
 
545
 
 
546
        return(bpage->space);
155
547
}
156
548
 
157
549
/*************************************************************************
160
552
ulint
161
553
buf_block_get_space(
162
554
/*================*/
163
 
                                /* out: space id */
164
 
        buf_block_t*    block)  /* in: pointer to the control block */
 
555
                                        /* out: space id */
 
556
        const buf_block_t*      block)  /* in: pointer to the control block */
165
557
{
166
558
        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);
 
559
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
 
560
 
 
561
        return(block->page.space);
 
562
}
 
563
 
 
564
/*************************************************************************
 
565
Gets the page number of a block. */
 
566
UNIV_INLINE
 
567
ulint
 
568
buf_page_get_page_no(
 
569
/*=================*/
 
570
                                        /* out: page number */
 
571
        const buf_page_t*       bpage)  /* in: pointer to the control block */
 
572
{
 
573
        ut_ad(bpage);
 
574
        ut_a(buf_page_in_file(bpage));
 
575
 
 
576
        return(bpage->offset);
173
577
}
174
578
 
175
579
/*************************************************************************
178
582
ulint
179
583
buf_block_get_page_no(
180
584
/*==================*/
181
 
                                /* out: page number */
182
 
        buf_block_t*    block)  /* in: pointer to the control block */
 
585
                                        /* out: page number */
 
586
        const buf_block_t*      block)  /* in: pointer to the control block */
183
587
{
184
588
        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
 
 
 
589
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
 
590
 
 
591
        return(block->page.offset);
 
592
}
 
593
 
 
594
/*************************************************************************
 
595
Gets the compressed page size of a block. */
 
596
UNIV_INLINE
 
597
ulint
 
598
buf_page_get_zip_size(
 
599
/*==================*/
 
600
                                        /* out: compressed page size, or 0 */
 
601
        const buf_page_t*       bpage)  /* in: pointer to the control block */
 
602
{
 
603
        return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
 
604
}
 
605
 
 
606
/*************************************************************************
 
607
Gets the compressed page size of a block. */
 
608
UNIV_INLINE
 
609
ulint
 
610
buf_block_get_zip_size(
 
611
/*===================*/
 
612
                                        /* out: compressed page size, or 0 */
 
613
        const buf_block_t*      block)  /* in: pointer to the control block */
 
614
{
 
615
        return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
 
616
}
 
617
 
 
618
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
193
619
/***********************************************************************
194
620
Gets the block to whose frame the pointer is pointing to. */
195
621
UNIV_INLINE
196
 
buf_block_t*
 
622
const buf_block_t*
197
623
buf_block_align(
198
624
/*============*/
199
 
                        /* out: pointer to block */
200
 
        byte*   ptr)    /* in: pointer to a frame */
 
625
                                /* out: pointer to block */
 
626
        const byte*     ptr)    /* in: pointer to a frame */
201
627
{
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));
 
628
        const buf_block_t*      block;
 
629
        ulint                   space_id, page_no;
 
630
 
 
631
        ptr = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
 
632
        page_no = mach_read_from_4(ptr + FIL_PAGE_OFFSET);
 
633
        space_id = mach_read_from_4(ptr + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 
634
 
 
635
        block = (const buf_block_t*) buf_page_hash_get(space_id, page_no);
 
636
        ut_ad(block);
 
637
        ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
 
638
        ut_ad(block->frame == ptr);
230
639
        return(block);
231
640
}
232
641
 
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(
 
642
/*************************************************************************
 
643
Gets the compressed page descriptor corresponding to an uncompressed page
 
644
if applicable. */
 
645
UNIV_INLINE
 
646
const page_zip_des_t*
 
647
buf_frame_get_page_zip(
289
648
/*===================*/
290
 
                        /* out: space id */
291
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
 
649
                                /* out: compressed page descriptor, or NULL */
 
650
        const byte*     ptr)    /* in: pointer to the page */
292
651
{
293
 
        return(buf_block_get_space(buf_block_align(ptr)));
 
652
        const page_zip_des_t*   page_zip;
 
653
        buf_pool_mutex_enter();
 
654
        page_zip = buf_block_get_page_zip(buf_block_align(ptr));
 
655
        buf_pool_mutex_exit();
 
656
        return(page_zip);
294
657
}
 
658
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
295
659
 
296
660
/**************************************************************************
297
661
Gets the space id, page offset, and byte offset within page of a
300
664
void
301
665
buf_ptr_get_fsp_addr(
302
666
/*=================*/
303
 
        byte*           ptr,    /* in: pointer to a buffer frame */
 
667
        const void*     ptr,    /* in: pointer to a buffer frame */
304
668
        ulint*          space,  /* out: space id */
305
669
        fil_addr_t*     addr)   /* out: page offset and byte offset */
306
670
{
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);
 
671
        const page_t*   page = (const page_t*) ut_align_down(ptr,
 
672
                                                             UNIV_PAGE_SIZE);
 
673
 
 
674
        *space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
 
675
        addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
 
676
        addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
314
677
}
315
678
 
316
679
/**************************************************************************
318
681
in searches in the lock hash table. */
319
682
UNIV_INLINE
320
683
ulint
321
 
buf_frame_get_lock_hash_val(
 
684
buf_block_get_lock_hash_val(
322
685
/*========================*/
323
 
                        /* out: lock hash value */
324
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
 
686
                                        /* out: lock hash value */
 
687
        const buf_block_t*      block)  /* in: block */
325
688
{
326
 
        buf_block_t*    block;
327
 
 
328
 
        block = buf_block_align(ptr);
329
 
 
330
689
        return(block->lock_hash_val);
331
690
}
332
691
 
333
 
/**************************************************************************
334
 
Gets the mutex number protecting the page record lock hash chain in the lock
335
 
table. */
 
692
/************************************************************************
 
693
Allocates a buffer block. */
336
694
UNIV_INLINE
337
 
mutex_t*
338
 
buf_frame_get_mutex(
339
 
/*================*/
340
 
                        /* out: mutex */
341
 
        byte*   ptr)    /* in: pointer to within a buffer frame */
 
695
buf_block_t*
 
696
buf_block_alloc(
 
697
/*============*/
 
698
                                /* out, own: the allocated block,
 
699
                                in state BUF_BLOCK_MEMORY */
 
700
        ulint   zip_size)       /* in: compressed page size in bytes,
 
701
                                or 0 if uncompressed tablespace */
342
702
{
343
703
        buf_block_t*    block;
344
704
 
345
 
        block = buf_block_align(ptr);
346
 
 
347
 
        return(&block->mutex);
 
705
        block = buf_LRU_get_free_block(zip_size);
 
706
 
 
707
        buf_block_set_state(block, BUF_BLOCK_MEMORY);
 
708
 
 
709
        return(block);
 
710
}
 
711
 
 
712
/************************************************************************
 
713
Frees a buffer block which does not contain a file page. */
 
714
UNIV_INLINE
 
715
void
 
716
buf_block_free(
 
717
/*===========*/
 
718
        buf_block_t*    block)  /* in, own: block to be freed */
 
719
{
 
720
        buf_pool_mutex_enter();
 
721
 
 
722
        mutex_enter(&block->mutex);
 
723
 
 
724
        ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
 
725
 
 
726
        buf_LRU_block_free_non_file_page(block);
 
727
 
 
728
        mutex_exit(&block->mutex);
 
729
 
 
730
        buf_pool_mutex_exit();
348
731
}
349
732
 
350
733
/*************************************************************************
353
736
byte*
354
737
buf_frame_copy(
355
738
/*===========*/
356
 
                                /* out: buf */
357
 
        byte*           buf,    /* in: buffer to copy to */
358
 
        buf_frame_t*    frame)  /* in: buffer frame */
 
739
                                        /* out: buf */
 
740
        byte*                   buf,    /* in: buffer to copy to */
 
741
        const buf_frame_t*      frame)  /* in: buffer frame */
359
742
{
360
743
        ut_ad(buf && frame);
361
744
 
386
769
buf_page_io_query(
387
770
/*==============*/
388
771
                                /* out: TRUE if io going on */
389
 
        buf_block_t*    block)  /* in: buf_pool block, must be bufferfixed */
 
772
        buf_page_t*     bpage)  /* in: buf_pool block, must be bufferfixed */
390
773
{
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);
 
774
        ibool   io_fixed;
 
775
 
 
776
        buf_pool_mutex_enter();
 
777
 
 
778
        ut_ad(buf_page_in_file(bpage));
 
779
        ut_ad(bpage->buf_fix_count > 0);
 
780
 
 
781
        io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
 
782
        buf_pool_mutex_exit();
 
783
 
 
784
        return(io_fixed);
405
785
}
406
786
 
407
787
/************************************************************************
408
 
Gets the youngest modification log sequence number for a frame. Returns zero
409
 
if not a file page or no modification occurred yet. */
 
788
Gets the youngest modification log sequence number for a frame.
 
789
Returns zero if not file page or no modification occurred yet. */
410
790
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 */
 
791
ib_uint64_t
 
792
buf_page_get_newest_modification(
 
793
/*=============================*/
 
794
                                        /* out: newest modification to page */
 
795
        const buf_page_t*       bpage)  /* in: block containing the
 
796
                                        page frame */
416
797
{
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;
 
798
        ib_uint64_t     lsn;
 
799
 
 
800
        buf_pool_mutex_enter();
 
801
 
 
802
        if (buf_page_in_file(bpage)) {
 
803
                lsn = bpage->newest_modification;
428
804
        } else {
429
 
                lsn = ut_dulint_zero;
 
805
                lsn = 0;
430
806
        }
431
807
 
432
 
        mutex_exit(&(buf_pool->mutex));
 
808
        buf_pool_mutex_exit();
433
809
 
434
810
        return(lsn);
435
811
}
439
815
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
440
816
on the block. */
441
817
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
 
818
void
470
819
buf_block_modify_clock_inc(
471
820
/*=======================*/
472
 
                                /* out: new value */
473
821
        buf_block_t*    block)  /* in: block */
474
822
{
475
823
#ifdef UNIV_SYNC_DEBUG
476
 
        ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
 
824
        ut_ad((buf_pool_mutex_own()
 
825
               && (block->page.buf_fix_count == 0))
477
826
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
478
827
#endif /* UNIV_SYNC_DEBUG */
479
828
 
480
 
        UT_DULINT_INC(block->modify_clock);
481
 
 
482
 
        return(block->modify_clock);
 
829
        block->modify_clock++;
483
830
}
484
831
 
485
832
/************************************************************************
486
833
Returns the value of the modify clock. The caller must have an s-lock
487
834
or x-lock on the block. */
488
835
UNIV_INLINE
489
 
dulint
 
836
ib_uint64_t
490
837
buf_block_get_modify_clock(
491
838
/*=======================*/
492
839
                                /* out: value */
500
847
        return(block->modify_clock);
501
848
}
502
849
 
503
 
#ifdef UNIV_SYNC_DEBUG
504
850
/***********************************************************************
505
851
Increments the bufferfix count. */
506
852
UNIV_INLINE
507
853
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 */
 
854
buf_block_buf_fix_inc_func(
 
855
/*=======================*/
 
856
#ifdef UNIV_SYNC_DEBUG
 
857
        const char*     file,   /* in: file name */
 
858
        ulint           line,   /* in: line */
 
859
#endif /* UNIV_SYNC_DEBUG */
 
860
        buf_block_t*    block)  /* in: block to bufferfix */
513
861
{
 
862
#ifdef UNIV_SYNC_DEBUG
514
863
        ibool   ret;
515
864
 
516
865
        ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
 
866
        ut_a(ret);
 
867
#endif /* UNIV_SYNC_DEBUG */
 
868
        ut_ad(mutex_own(&block->mutex));
517
869
 
518
 
        ut_ad(ret == TRUE);
519
 
        ut_ad(mutex_own(&block->mutex));
520
 
        block->buf_fix_count++;
 
870
        block->page.buf_fix_count++;
521
871
}
 
872
#ifdef UNIV_SYNC_DEBUG
 
873
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
522
874
#else /* UNIV_SYNC_DEBUG */
 
875
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
 
876
#endif /* UNIV_SYNC_DEBUG */
 
877
 
523
878
/***********************************************************************
524
 
Increments the bufferfix count. */
 
879
Decrements the bufferfix count. */
525
880
UNIV_INLINE
526
881
void
527
 
buf_block_buf_fix_inc(
 
882
buf_block_buf_fix_dec(
528
883
/*==================*/
529
 
        buf_block_t*    block)  /* in: block to bufferfix */
 
884
        buf_block_t*    block)  /* in: block to bufferunfix */
530
885
{
531
886
        ut_ad(mutex_own(&block->mutex));
532
887
 
533
 
        block->buf_fix_count++;
 
888
        block->page.buf_fix_count--;
 
889
#ifdef UNIV_SYNC_DEBUG
 
890
        rw_lock_s_unlock(&block->debug_latch);
 
891
#endif
534
892
}
535
 
#endif /* UNIV_SYNC_DEBUG */
 
893
 
536
894
/**********************************************************************
537
895
Returns the control block of a file page, NULL if not found. */
538
896
UNIV_INLINE
539
 
buf_block_t*
 
897
buf_page_t*
540
898
buf_page_hash_get(
541
899
/*==============*/
542
900
                        /* out: block, NULL if not found */
543
901
        ulint   space,  /* in: space id */
544
902
        ulint   offset) /* in: offset of the page within space */
545
903
{
546
 
        buf_block_t*    block;
 
904
        buf_page_t*     bpage;
547
905
        ulint           fold;
548
906
 
549
907
        ut_ad(buf_pool);
550
 
        ut_ad(mutex_own(&(buf_pool->mutex)));
 
908
        ut_ad(buf_pool_mutex_own());
551
909
 
552
910
        /* Look for the page in the hash table */
553
911
 
554
912
        fold = buf_page_address_fold(space, offset);
555
913
 
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);
 
914
        HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
 
915
                    bpage->space == space && bpage->offset == offset);
 
916
        if (bpage) {
 
917
                ut_a(buf_page_in_file(bpage));
 
918
                ut_ad(bpage->in_page_hash);
 
919
                ut_ad(!bpage->in_zip_hash);
 
920
                UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
 
921
        }
 
922
 
 
923
        return(bpage);
 
924
}
 
925
 
 
926
/**********************************************************************
 
927
Returns the control block of a file page, NULL if not found
 
928
or an uncompressed page frame does not exist. */
 
929
UNIV_INLINE
 
930
buf_block_t*
 
931
buf_block_hash_get(
 
932
/*===============*/
 
933
                        /* out: block, NULL if not found */
 
934
        ulint   space,  /* in: space id */
 
935
        ulint   offset) /* in: offset of the page within space */
 
936
{
 
937
        return(buf_page_get_block(buf_page_hash_get(space, offset)));
 
938
}
 
939
 
 
940
/************************************************************************
 
941
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
 
942
that it is possible that the page is not yet read from disk, though. */
 
943
UNIV_INLINE
 
944
ibool
 
945
buf_page_peek(
 
946
/*==========*/
 
947
                        /* out: TRUE if found from page hash table,
 
948
                        NOTE that the page is not necessarily yet read
 
949
                        from disk! */
 
950
        ulint   space,  /* in: space id */
 
951
        ulint   offset) /* in: page number */
 
952
{
 
953
        const buf_page_t*       bpage;
 
954
 
 
955
        buf_pool_mutex_enter();
 
956
 
 
957
        bpage = buf_page_hash_get(space, offset);
 
958
 
 
959
        buf_pool_mutex_exit();
 
960
 
 
961
        return(bpage != NULL);
 
962
}
 
963
 
 
964
/************************************************************************
 
965
Releases a compressed-only page acquired with buf_page_get_zip(). */
 
966
UNIV_INLINE
 
967
void
 
968
buf_page_release_zip(
 
969
/*=================*/
 
970
        buf_page_t*     bpage)          /* in: buffer block */
 
971
{
 
972
        buf_block_t*    block;
 
973
 
 
974
        ut_ad(bpage);
 
975
        ut_a(bpage->buf_fix_count > 0);
 
976
 
 
977
        switch (buf_page_get_state(bpage)) {
 
978
        case BUF_BLOCK_ZIP_PAGE:
 
979
        case BUF_BLOCK_ZIP_DIRTY:
 
980
                mutex_enter(&buf_pool_zip_mutex);
 
981
                bpage->buf_fix_count--;
 
982
                mutex_exit(&buf_pool_zip_mutex);
 
983
                return;
 
984
        case BUF_BLOCK_FILE_PAGE:
 
985
                block = (buf_block_t*) bpage;
 
986
                mutex_enter(&block->mutex);
 
987
#ifdef UNIV_SYNC_DEBUG
 
988
                rw_lock_s_unlock(&block->debug_latch);
 
989
#endif
 
990
                bpage->buf_fix_count--;
 
991
                mutex_exit(&block->mutex);
 
992
                return;
 
993
        case BUF_BLOCK_ZIP_FREE:
 
994
        case BUF_BLOCK_NOT_USED:
 
995
        case BUF_BLOCK_READY_FOR_USE:
 
996
        case BUF_BLOCK_MEMORY:
 
997
        case BUF_BLOCK_REMOVE_HASH:
 
998
                break;
 
999
        }
 
1000
 
 
1001
        ut_error;
607
1002
}
608
1003
 
609
1004
/************************************************************************
620
1015
{
621
1016
        ut_ad(block);
622
1017
 
623
 
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
624
 
        ut_a(block->buf_fix_count > 0);
 
1018
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
 
1019
        ut_a(block->page.buf_fix_count > 0);
625
1020
 
626
1021
        if (rw_latch == RW_X_LATCH && mtr->modifications) {
627
 
                mutex_enter(&buf_pool->mutex);
 
1022
                buf_pool_mutex_enter();
628
1023
                buf_flush_note_modification(block, mtr);
629
 
                mutex_exit(&buf_pool->mutex);
 
1024
                buf_pool_mutex_exit();
630
1025
        }
631
1026
 
632
1027
        mutex_enter(&block->mutex);
634
1029
#ifdef UNIV_SYNC_DEBUG
635
1030
        rw_lock_s_unlock(&(block->debug_latch));
636
1031
#endif
637
 
        block->buf_fix_count--;
 
1032
        block->page.buf_fix_count--;
638
1033
 
639
1034
        mutex_exit(&block->mutex);
640
1035
 
649
1044
/*************************************************************************
650
1045
Adds latch level info for the rw-lock protecting the buffer frame. This
651
1046
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. */
 
1047
page if we know the latching order level of the acquired latch. */
654
1048
UNIV_INLINE
655
1049
void
656
 
buf_page_dbg_add_level(
657
 
/*===================*/
658
 
        buf_frame_t*    frame __attribute__((unused)), /* in: buffer page
 
1050
buf_block_dbg_add_level(
 
1051
/*====================*/
 
1052
        buf_block_t*    block,  /* in: buffer page
659
1053
                                where we have acquired latch */
660
 
        ulint           level __attribute__((unused))) /* in: latching order
661
 
                                level */
 
1054
        ulint           level)  /* in: latching order level */
662
1055
{
663
 
        sync_thread_add_level(&(buf_block_align(frame)->lock), level);
 
1056
        sync_thread_add_level(&block->lock, level);
664
1057
}
665
1058
#endif /* UNIV_SYNC_DEBUG */