Commit 13049a9e 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 c20a0d95
......@@ -165,7 +165,8 @@ buf_buddy_alloc_clean(
ut_a(mutex_own(&buf_pool->mutex));
#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
of the same size. */
......@@ -225,11 +226,21 @@ buf_buddy_alloc_clean(
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(
/*================*/
/* out: allocated block, or NULL
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 */
{
buf_block_t* block;
......@@ -253,12 +265,14 @@ buf_buddy_alloc_low(
ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */
/* Try to allocate from the buddy system. */
block = buf_buddy_alloc_zip(i);
if (i < BUF_BUDDY_SIZES) {
/* 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. */
......@@ -441,6 +455,11 @@ buf_buddy_free_low(
ut_a(mutex_own(&buf_pool->mutex));
#endif /* UNIV_SYNC_DEBUG */
recombine:
if (i == BUF_BUDDY_SIZES) {
buf_buddy_block_free(buf);
return;
}
ut_ad(i < BUF_BUDDY_SIZES);
ut_ad(buf == ut_align_down(buf, BUF_BUDDY_LOW << i));
ut_ad(!buf_pool_contains_zip(buf));
......@@ -468,16 +487,10 @@ buf_buddy_free_low(
UT_LIST_REMOVE(list, buf_pool->zip_free[i], bpage);
buddy_free2:
ut_ad(!buf_pool_contains_zip(buddy));
buf = ut_align_down(buf, BUF_BUDDY_LOW << (i + 1));
if (++i < BUF_BUDDY_SIZES) {
goto recombine;
}
i++;
buf = ut_align_down(buf, BUF_BUDDY_LOW << i);
/* The whole block is free. */
buf_buddy_block_free(buf);
return;
goto recombine;
}
ut_a(bpage != buf);
......
......@@ -39,7 +39,8 @@ UNIV_INLINE
ulint
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 */
/**************************************************************************
......@@ -49,7 +50,7 @@ void*
buf_buddy_alloc(
/*============*/
/* 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 */
__attribute__((malloc));
......@@ -61,7 +62,7 @@ buf_buddy_free(
/*===========*/
void* buf, /* in: block to be freed, must not be
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));
#ifndef UNIV_NONINL
......
......@@ -25,7 +25,8 @@ void*
buf_buddy_alloc_low(
/*================*/
/* 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 */
__attribute__((malloc));
......@@ -37,7 +38,8 @@ buf_buddy_free_low(
/*===============*/
void* buf, /* in: block to be freed, must not be
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));
/**************************************************************************
......@@ -67,7 +69,8 @@ UNIV_INLINE
ulint
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 i;
......@@ -75,7 +78,7 @@ buf_buddy_get_slot(
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);
}
......@@ -86,7 +89,7 @@ void*
buf_buddy_alloc(
/*============*/
/* 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 */
{
#ifdef UNIV_SYNC_DEBUG
......@@ -104,7 +107,7 @@ buf_buddy_free(
/*===========*/
void* buf, /* in: block to be freed, must not be
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
ut_a(mutex_own(&buf_pool->mutex));
......
......@@ -70,7 +70,7 @@ enum buf_page_state {
BUF_BLOCK_NOT_USED; @see buf_block_state_valid() */
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 */
BUF_BLOCK_FILE_PAGE, /* contains a buffered file page */
BUF_BLOCK_MEMORY, /* contains some main memory object */
......@@ -912,8 +912,8 @@ for compressed and uncompressed frames */
struct buf_page_struct{
/* None of the following bit-fields must be modified without
holding block->mutex or buf_pool->zip_mutex, since they can be
stored in the same machine word. Some of them are
holding buf_page_get_mutex() [block->mutex or buf_pool->zip_mutex],
since they can be stored in the same machine word. Some of them are
additionally protected by buf_pool->mutex. */
unsigned space:32; /* tablespace id */
......@@ -921,7 +921,11 @@ struct buf_page_struct{
unsigned state:3; /* state of the control block
(@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
flushed to disk, this tells the
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