From 10c92bd7ac995f385c231f4db1564e1e6411f469 Mon Sep 17 00:00:00 2001 From: marko <> Date: Tue, 9 Jan 2007 12:39:50 +0000 Subject: [PATCH] branches/zip: buf_buddy_alloc_clean(): Restart the scan after a successful buf_LRU_free_block(). buf_LRU_free_block(): Note that buf_pool->mutex may be temporarily released. --- buf/buf0buddy.c | 14 ++++++++++++++ buf/buf0lru.c | 7 ++++++- include/buf0lru.h | 7 ++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/buf/buf0buddy.c b/buf/buf0buddy.c index 59a1d4146cc..eb0ea680507 100644 --- a/buf/buf0buddy.c +++ b/buf/buf0buddy.c @@ -234,6 +234,7 @@ buf_buddy_alloc_clean( /* Free blocks from the end of the LRU list until enough space is available. */ +free_LRU: for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage; bpage = UT_LIST_GET_PREV(LRU, bpage)) { @@ -258,6 +259,9 @@ buf_buddy_alloc_clean( mutex_exit(block_mutex); + /* The block was successfully freed. + Attempt to allocate memory. */ + if (i < BUF_BUDDY_SIZES) { ret = buf_buddy_alloc_zip(i); @@ -274,6 +278,16 @@ buf_buddy_alloc_clean( return(block->frame); } } + + /* A successful buf_LRU_free_block() may release and + reacquire buf_pool->mutex, and thus bpage->LRU of + an uncompressed page may point to garbage. Furthermore, + if bpage were a compressed page descriptor, it would + have been deallocated by buf_LRU_free_block(). + + Thus, we must restart the traversal of the LRU list. */ + + goto free_LRU; } return(NULL); diff --git a/buf/buf0lru.c b/buf/buf0lru.c index a6e8fc9afce..beb7358b13f 100644 --- a/buf/buf0lru.c +++ b/buf/buf0lru.c @@ -878,7 +878,12 @@ Try to free a block. */ ibool buf_LRU_free_block( /*===============*/ - /* out: TRUE if freed */ + /* out: TRUE if freed. If bpage is a + descriptor of a compressed-only page, + the descriptor object will be freed + as well. If this function returns FALSE, + it will not temporarily release + buf_pool->mutex. */ buf_page_t* bpage, /* in: block to be freed */ ibool zip) /* in: TRUE if should remove also the compressed page of an uncompressed page */ diff --git a/include/buf0lru.h b/include/buf0lru.h index a0c1b16ca57..f6a1e1a3d2c 100644 --- a/include/buf0lru.h +++ b/include/buf0lru.h @@ -78,7 +78,12 @@ Try to free a block. */ ibool buf_LRU_free_block( /*===============*/ - /* out: TRUE if freed */ + /* out: TRUE if freed. If bpage is a + descriptor of a compressed-only page, + the descriptor object will be freed + as well. If this function returns FALSE, + it will not temporarily release + buf_pool->mutex. */ buf_page_t* block, /* in: block to be freed */ ibool zip); /* in: TRUE if should remove also the compressed page of an uncompressed page */