Commit f54da50c authored by marko's avatar marko

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.
parent d3917bb5
...@@ -234,6 +234,7 @@ buf_buddy_alloc_clean( ...@@ -234,6 +234,7 @@ buf_buddy_alloc_clean(
/* Free blocks from the end of the LRU list until enough space /* Free blocks from the end of the LRU list until enough space
is available. */ is available. */
free_LRU:
for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage; for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage;
bpage = UT_LIST_GET_PREV(LRU, bpage)) { bpage = UT_LIST_GET_PREV(LRU, bpage)) {
...@@ -258,6 +259,9 @@ buf_buddy_alloc_clean( ...@@ -258,6 +259,9 @@ buf_buddy_alloc_clean(
mutex_exit(block_mutex); mutex_exit(block_mutex);
/* The block was successfully freed.
Attempt to allocate memory. */
if (i < BUF_BUDDY_SIZES) { if (i < BUF_BUDDY_SIZES) {
ret = buf_buddy_alloc_zip(i); ret = buf_buddy_alloc_zip(i);
...@@ -274,6 +278,16 @@ buf_buddy_alloc_clean( ...@@ -274,6 +278,16 @@ buf_buddy_alloc_clean(
return(block->frame); 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); return(NULL);
......
...@@ -878,7 +878,12 @@ Try to free a block. */ ...@@ -878,7 +878,12 @@ Try to free a block. */
ibool ibool
buf_LRU_free_block( 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 */ buf_page_t* bpage, /* in: block to be freed */
ibool zip) /* in: TRUE if should remove also the ibool zip) /* in: TRUE if should remove also the
compressed page of an uncompressed page */ compressed page of an uncompressed page */
......
...@@ -78,7 +78,12 @@ Try to free a block. */ ...@@ -78,7 +78,12 @@ Try to free a block. */
ibool ibool
buf_LRU_free_block( 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 */ buf_page_t* block, /* in: block to be freed */
ibool zip); /* in: TRUE if should remove also the ibool zip); /* in: TRUE if should remove also the
compressed page of an uncompressed page */ compressed page of an uncompressed page */
......
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