buf0buddy.ic 4.51 KB
Newer Older
Vadim Tkachenko's avatar
Vadim Tkachenko committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*****************************************************************************

Copyright (c) 2006, 2009, Innobase Oy. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA

*****************************************************************************/

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
19 20
/**************************************************//**
@file include/buf0buddy.ic
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
Binary buddy allocator for compressed pages

Created December 2006 by Marko Makela
*******************************************************/

#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE
#endif

#include "buf0buf.h"
#include "buf0buddy.h"
#include "ut0ut.h"
#include "sync0sync.h"

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
36
/**********************************************************************//**
37 38
Allocate a block.  The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any block->mutex.
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
39 40
The buf_pool_mutex may only be released and reacquired if lru != NULL.
@return	allocated block, possibly NULL if lru==NULL */
41 42 43 44
UNIV_INTERN
void*
buf_buddy_alloc_low(
/*================*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
45
	ulint	i,	/*!< in: index of buf_pool->zip_free[],
46
			or BUF_BUDDY_SIZES */
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
47
	ibool*	lru,	/*!< in: pointer to a variable that will be assigned
48 49 50
			TRUE if storage was allocated from the LRU list
			and buf_pool_mutex was temporarily released,
			or NULL if the LRU list should not be used */
Vadim Tkachenko's avatar
Vadim Tkachenko committed
51
	ibool	have_page_hash_mutex)
52 53
	__attribute__((malloc));

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
54
/**********************************************************************//**
55 56 57 58 59
Deallocate a block. */
UNIV_INTERN
void
buf_buddy_free_low(
/*===============*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
60
	void*	buf,	/*!< in: block to be freed, must not be
61
			pointed to by the buffer pool */
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
62
	ulint	i,	/*!< in: index of buf_pool->zip_free[],
63
			or BUF_BUDDY_SIZES */
Vadim Tkachenko's avatar
Vadim Tkachenko committed
64
	ibool	have_page_hash_mutex)
65 66
	__attribute__((nonnull));

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
67 68 69
/**********************************************************************//**
Get the index of buf_pool->zip_free[] for a given block size.
@return	index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */
70 71 72 73
UNIV_INLINE
ulint
buf_buddy_get_slot(
/*===============*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
74
	ulint	size)	/*!< in: block size */
75 76 77 78
{
	ulint	i;
	ulint	s;

Vadim Tkachenko's avatar
Vadim Tkachenko committed
79 80
	for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1) {
	}
81 82 83 84 85

	ut_ad(i <= BUF_BUDDY_SIZES);
	return(i);
}

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
86
/**********************************************************************//**
87 88 89 90 91 92 93
Allocate a block.  The thread calling this function must hold
buf_pool_mutex and must not hold buf_pool_zip_mutex or any
block->mutex.  The buf_pool_mutex may only be released and reacquired
if lru != NULL.  This function should only be used for allocating
compressed page frames or control blocks (buf_page_t).  Allocated
control blocks must be properly initialized immediately after
buf_buddy_alloc() has returned the memory, before releasing
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
94 95
buf_pool_mutex.
@return	allocated block, possibly NULL if lru == NULL */
96 97 98 99
UNIV_INLINE
void*
buf_buddy_alloc(
/*============*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
100 101
	ulint	size,	/*!< in: block size, up to UNIV_PAGE_SIZE */
	ibool*	lru,	/*!< in: pointer to a variable that will be assigned
102 103 104
			TRUE if storage was allocated from the LRU list
			and buf_pool_mutex was temporarily released,
			or NULL if the LRU list should not be used */
Vadim Tkachenko's avatar
Vadim Tkachenko committed
105
	ibool	have_page_hash_mutex)
106
{
Vadim Tkachenko's avatar
Vadim Tkachenko committed
107
	//ut_ad(buf_pool_mutex_own());
108

Vadim Tkachenko's avatar
Vadim Tkachenko committed
109
	return(buf_buddy_alloc_low(buf_buddy_get_slot(size), lru, have_page_hash_mutex));
110 111
}

Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
112
/**********************************************************************//**
113 114 115 116 117
Deallocate a block. */
UNIV_INLINE
void
buf_buddy_free(
/*===========*/
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
118
	void*	buf,	/*!< in: block to be freed, must not be
119
			pointed to by the buffer pool */
Aleksandr Kuzminsky's avatar
Aleksandr Kuzminsky committed
120
	ulint	size,	/*!< in: block size, up to UNIV_PAGE_SIZE */
Vadim Tkachenko's avatar
Vadim Tkachenko committed
121
	ibool	have_page_hash_mutex)
122
{
Vadim Tkachenko's avatar
Vadim Tkachenko committed
123 124 125 126 127 128 129 130 131 132
	//ut_ad(buf_pool_mutex_own());

	if (!have_page_hash_mutex) {
		mutex_enter(&LRU_list_mutex);
		rw_lock_x_lock(&page_hash_latch);
	}

	mutex_enter(&zip_free_mutex);
	buf_buddy_free_low(buf, buf_buddy_get_slot(size), TRUE);
	mutex_exit(&zip_free_mutex);
133

Vadim Tkachenko's avatar
Vadim Tkachenko committed
134 135 136 137
	if (!have_page_hash_mutex) {
		mutex_exit(&LRU_list_mutex);
		rw_lock_x_unlock(&page_hash_latch);
	}
138 139 140 141 142 143
}

#ifdef UNIV_MATERIALIZE
# undef UNIV_INLINE
# define UNIV_INLINE	UNIV_INLINE_ORIGINAL
#endif