Commit 9244a3a5 authored by marko's avatar marko

branches/zip: Allow the buddy allocator to work for 16-kilobyte pages,

twice the maximum block size of the buddy system.

buf_page_t: Note that state may change from BUF_BLOCK_READY_FOR_USE
to BUF_BLOCK_MEMORY without buf_page_get_mutex() protection
[only buf_pool->mutex].

buf_buddy_get_slot(): Extend the output to BUF_BUDDY_SIZES.

buf_buddy_alloc(), buf_buddy_free(): Allow sizes up to UNIV_PAGE_SIZE.

buf_buddy_alloc_low(), buf_buddy_free_low(), buf_buddy_alloc_clean():
Allow i==BUF_BUDDY_SIZES.
parent 77417e46
...@@ -165,7 +165,8 @@ buf_buddy_alloc_clean( ...@@ -165,7 +165,8 @@ buf_buddy_alloc_clean(
ut_a(mutex_own(&buf_pool->mutex)); ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
if (BUF_BUDDY_LOW << i >= PAGE_ZIP_MIN_SIZE) { if (BUF_BUDDY_LOW << i >= PAGE_ZIP_MIN_SIZE
&& i < BUF_BUDDY_SIZES) {
/* Try to find a clean compressed-only page /* Try to find a clean compressed-only page
of the same size. */ of the same size. */
...@@ -225,11 +226,21 @@ buf_buddy_alloc_clean( ...@@ -225,11 +226,21 @@ buf_buddy_alloc_clean(
mutex_exit(block_mutex); mutex_exit(block_mutex);
ret = buf_buddy_alloc_zip(i); if (i < BUF_BUDDY_SIZES) {
if (ret) { ret = buf_buddy_alloc_zip(i);
return(ret); if (ret) {
return(ret);
}
} else {
buf_block_t* block = buf_LRU_get_free_only();
if (block) {
buf_buddy_block_register(block);
return(block->frame);
}
} }
} }
...@@ -244,7 +255,8 @@ buf_buddy_alloc_low( ...@@ -244,7 +255,8 @@ buf_buddy_alloc_low(
/*================*/ /*================*/
/* out: allocated block, or NULL /* out: allocated block, or NULL
if buf_pool->zip_free[] was empty */ if buf_pool->zip_free[] was empty */
ulint i, /* in: index of buf_pool->zip_free[] */ ulint i, /* in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool lru) /* in: TRUE=allocate from the LRU list if needed */ ibool lru) /* in: TRUE=allocate from the LRU list if needed */
{ {
buf_block_t* block; buf_block_t* block;
...@@ -253,12 +265,14 @@ buf_buddy_alloc_low( ...@@ -253,12 +265,14 @@ buf_buddy_alloc_low(
ut_a(mutex_own(&buf_pool->mutex)); ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
/* Try to allocate from the buddy system. */ if (i < BUF_BUDDY_SIZES) {
block = buf_buddy_alloc_zip(i); /* Try to allocate from the buddy system. */
block = buf_buddy_alloc_zip(i);
if (block) { if (block) {
return(block); return(block);
}
} }
/* Try allocating from the buf_pool->free list. */ /* Try allocating from the buf_pool->free list. */
...@@ -441,6 +455,11 @@ buf_buddy_free_low( ...@@ -441,6 +455,11 @@ buf_buddy_free_low(
ut_a(mutex_own(&buf_pool->mutex)); ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
recombine: recombine:
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf);
return;
}
ut_ad(i < BUF_BUDDY_SIZES); ut_ad(i < BUF_BUDDY_SIZES);
ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i)); ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buf)); ut_ad(!buf_pool_contains_zip(buf));
...@@ -468,16 +487,10 @@ buddy_free: ...@@ -468,16 +487,10 @@ buddy_free:
UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage); UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
buddy_free2: buddy_free2:
ut_ad(!buf_pool_contains_zip(buddy)); ut_ad(!buf_pool_contains_zip(buddy));
buf = ut_align_down(buf, BUF_BUDDY_LOW << (i + 1)); i++;
buf = ut_align_down(buf, BUF_BUDDY_LOW << i);
if (++i < BUF_BUDDY_SIZES) {
goto recombine;
}
/* The whole block is free. */ goto recombine;
buf_buddy_block_free(buf);
return;
} }
ut_a(bpage != buf); ut_a(bpage != buf);
......
...@@ -39,7 +39,8 @@ UNIV_INLINE ...@@ -39,7 +39,8 @@ UNIV_INLINE
ulint ulint
buf_buddy_get_slot( buf_buddy_get_slot(
/*===============*/ /*===============*/
/* out: index of buf_pool->zip_free[] */ /* out: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ulint size); /* in: block size */ ulint size); /* in: block size */
/************************************************************************** /**************************************************************************
...@@ -49,7 +50,7 @@ void* ...@@ -49,7 +50,7 @@ void*
buf_buddy_alloc( buf_buddy_alloc(
/*============*/ /*============*/
/* out: pointer to the start of the block */ /* out: pointer to the start of the block */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool lru) /* in: TRUE=allocate from the LRU list if needed */ ibool lru) /* in: TRUE=allocate from the LRU list if needed */
__attribute__((malloc)); __attribute__((malloc));
...@@ -61,7 +62,7 @@ buf_buddy_free( ...@@ -61,7 +62,7 @@ buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size) /* in: block size, up to UNIV_PAGE_SIZE */
__attribute__((nonnull)); __attribute__((nonnull));
#ifndef UNIV_NONINL #ifndef UNIV_NONINL
......
...@@ -25,7 +25,8 @@ void* ...@@ -25,7 +25,8 @@ void*
buf_buddy_alloc_low( buf_buddy_alloc_low(
/*================*/ /*================*/
/* out: pointer to the start of the block */ /* out: pointer to the start of the block */
ulint i, /* in: index of buf_pool->zip_free[] */ ulint i, /* in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ibool lru) /* in: TRUE=allocate from the LRU list if needed */ ibool lru) /* in: TRUE=allocate from the LRU list if needed */
__attribute__((malloc)); __attribute__((malloc));
...@@ -37,7 +38,8 @@ buf_buddy_free_low( ...@@ -37,7 +38,8 @@ buf_buddy_free_low(
/*===============*/ /*===============*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint i) /* in: index of buf_pool->zip_free[] */ ulint i) /* in: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
__attribute__((nonnull)); __attribute__((nonnull));
/************************************************************************** /**************************************************************************
...@@ -67,7 +69,8 @@ UNIV_INLINE ...@@ -67,7 +69,8 @@ UNIV_INLINE
ulint ulint
buf_buddy_get_slot( buf_buddy_get_slot(
/*===============*/ /*===============*/
/* out: index of buf_pool->zip_free[] */ /* out: index of buf_pool->zip_free[],
or BUF_BUDDY_SIZES */
ulint size) /* in: block size */ ulint size) /* in: block size */
{ {
ulint i; ulint i;
...@@ -75,7 +78,7 @@ buf_buddy_get_slot( ...@@ -75,7 +78,7 @@ buf_buddy_get_slot(
for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1); for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1);
ut_ad(i < BUF_BUDDY_SIZES); ut_ad(i <= BUF_BUDDY_SIZES);
return(i); return(i);
} }
...@@ -86,7 +89,7 @@ void* ...@@ -86,7 +89,7 @@ void*
buf_buddy_alloc( buf_buddy_alloc(
/*============*/ /*============*/
/* out: pointer to the start of the block */ /* out: pointer to the start of the block */
ulint size, /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size, /* in: block size, up to UNIV_PAGE_SIZE */
ibool lru) /* in: TRUE=allocate from the LRU list if needed */ ibool lru) /* in: TRUE=allocate from the LRU list if needed */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
...@@ -104,7 +107,7 @@ buf_buddy_free( ...@@ -104,7 +107,7 @@ buf_buddy_free(
/*===========*/ /*===========*/
void* buf, /* in: block to be freed, must not be void* buf, /* in: block to be freed, must not be
pointed to by the buffer pool */ pointed to by the buffer pool */
ulint size) /* in: block size, up to UNIV_PAGE_SIZE / 2 */ ulint size) /* in: block size, up to UNIV_PAGE_SIZE */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_a(mutex_own(&buf_pool->mutex)); ut_a(mutex_own(&buf_pool->mutex));
......
...@@ -70,7 +70,7 @@ enum buf_page_state { ...@@ -70,7 +70,7 @@ enum buf_page_state {
BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */ BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */
BUF_BLOCK_NOT_USED, /* is in the free list */ BUF_BLOCK_NOT_USED, /* is in the free list */
BUF_BLOCK_READY_FOR_USE, /* when buf_get_free_block returns BUF_BLOCK_READY_FOR_USE, /* when buf_LRU_get_free_block returns
a block, it is in this state */ a block, it is in this state */
BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */ BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */
BUF_BLOCK_MEMORY, /* contains some main memory object */ BUF_BLOCK_MEMORY, /* contains some main memory object */
...@@ -912,8 +912,8 @@ for compressed and uncompressed frames */ ...@@ -912,8 +912,8 @@ for compressed and uncompressed frames */
struct buf_page_struct{ struct buf_page_struct{
/* None of the following bit-fields must be modified without /* None of the following bit-fields must be modified without
holding block->mutex or buf_pool->zip_mutex, since they can be holding buf_page_get_mutex() [block->mutex or buf_pool->zip_mutex],
stored in the same machine word. Some of them are since they can be stored in the same machine word. Some of them are
additionally protected by buf_pool->mutex. */ additionally protected by buf_pool->mutex. */
unsigned space:32; /* tablespace id */ unsigned space:32; /* tablespace id */
...@@ -921,7 +921,11 @@ struct buf_page_struct{ ...@@ -921,7 +921,11 @@ struct buf_page_struct{
unsigned state:3; /* state of the control block unsigned state:3; /* state of the control block
(@see enum buf_page_state); also (@see enum buf_page_state); also
protected by buf_pool->mutex */ protected by buf_pool->mutex.
State transitions from
BUF_BLOCK_READY_FOR_USE to
BUF_BLOCK_MEMORY need not be
protected by buf_page_get_mutex(). */
unsigned flush_type:2; /* if this block is currently being unsigned flush_type:2; /* if this block is currently being
flushed to disk, this tells the flushed to disk, this tells the
flush_type (@see enum buf_flush) */ flush_type (@see enum buf_flush) */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment