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.
This commit is contained in:
marko 2007-01-09 12:39:50 +00:00
parent 8af159117e
commit 10c92bd7ac
3 changed files with 26 additions and 2 deletions

View file

@ -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);

View file

@ -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 */

View file

@ -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 */