1/*****************************************************************************
2
3Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License, version 2.0,
7as published by the Free Software Foundation.
8
9This program is also distributed with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation.  The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have included with MySQL.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License, version 2.0, for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24
25*****************************************************************************/
26
27/**************************************************//**
28@file include/buf0buddy.ic
29Binary buddy allocator for compressed pages
30
31Created December 2006 by Marko Makela
32*******************************************************/
33
34#ifdef UNIV_MATERIALIZE
35# undef UNIV_INLINE
36# define UNIV_INLINE
37#endif
38
39#include "buf0buf.h"
40#include "buf0buddy.h"
41#include "ut0ut.h"
42#include "sync0sync.h"
43
44/**********************************************************************//**
45Allocate a block.  The thread calling this function must hold
46buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex.
47The buf_pool_mutex may be released and reacquired.
48@return	allocated block, never NULL */
49UNIV_INTERN
50void*
51buf_buddy_alloc_low(
52/*================*/
53	buf_pool_t*	buf_pool,	/*!< in/out: buffer pool instance */
54	ulint		i,		/*!< in: index of buf_pool->zip_free[],
55					or BUF_BUDDY_SIZES */
56	ibool*		lru)		/*!< in: pointer to a variable that
57					will be assigned TRUE if storage was
58					allocated from the LRU list and
59					buf_pool->mutex was temporarily
60					released */
61	MY_ATTRIBUTE((malloc, nonnull));
62
63/**********************************************************************//**
64Deallocate a block. */
65UNIV_INTERN
66void
67buf_buddy_free_low(
68/*===============*/
69	buf_pool_t*	buf_pool,	/*!< in: buffer pool instance */
70	void*		buf,		/*!< in: block to be freed, must not be
71					pointed to by the buffer pool */
72	ulint		i)		/*!< in: index of buf_pool->zip_free[],
73					or BUF_BUDDY_SIZES */
74	MY_ATTRIBUTE((nonnull));
75
76/**********************************************************************//**
77Get the index of buf_pool->zip_free[] for a given block size.
78@return	index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */
79UNIV_INLINE
80ulint
81buf_buddy_get_slot(
82/*===============*/
83	ulint	size)	/*!< in: block size */
84{
85	ulint	i;
86	ulint	s;
87
88	ut_ad(size >= UNIV_ZIP_SIZE_MIN);
89
90	for (i = 0, s = BUF_BUDDY_LOW; s < size; i++, s <<= 1) {
91	}
92
93	ut_ad(i <= BUF_BUDDY_SIZES);
94	return(i);
95}
96
97/**********************************************************************//**
98Allocate a block.  The thread calling this function must hold
99buf_pool->mutex and must not hold buf_pool->zip_mutex or any
100block->mutex.  The buf_pool->mutex may be released and reacquired.
101This function should only be used for allocating compressed page frames.
102@return	allocated block, never NULL */
103UNIV_INLINE
104byte*
105buf_buddy_alloc(
106/*============*/
107	buf_pool_t*	buf_pool,	/*!< in/out: buffer pool in which
108					the page resides */
109	ulint		size,		/*!< in: compressed page size
110					(between UNIV_ZIP_SIZE_MIN and
111					UNIV_PAGE_SIZE) */
112	ibool*		lru)		/*!< in: pointer to a variable
113					that will be assigned TRUE if
114				       	storage was allocated from the
115				       	LRU list and buf_pool->mutex was
116				       	temporarily released */
117{
118	ut_ad(buf_pool_mutex_own(buf_pool));
119	ut_ad(ut_is_2pow(size));
120	ut_ad(size >= UNIV_ZIP_SIZE_MIN);
121	ut_ad(size <= UNIV_PAGE_SIZE);
122
123	return((byte*) buf_buddy_alloc_low(buf_pool, buf_buddy_get_slot(size),
124					   lru));
125}
126
127/**********************************************************************//**
128Deallocate a block. */
129UNIV_INLINE
130void
131buf_buddy_free(
132/*===========*/
133	buf_pool_t*	buf_pool,	/*!< in/out: buffer pool in which
134					the block resides */
135	void*		buf,		/*!< in: block to be freed, must not
136					be pointed to by the buffer pool */
137	ulint		size)		/*!< in: block size,
138					up to UNIV_PAGE_SIZE */
139{
140	ut_ad(buf_pool_mutex_own(buf_pool));
141	ut_ad(ut_is_2pow(size));
142	ut_ad(size >= UNIV_ZIP_SIZE_MIN);
143	ut_ad(size <= UNIV_PAGE_SIZE);
144
145	buf_buddy_free_low(buf_pool, buf, buf_buddy_get_slot(size));
146}
147
148#ifdef UNIV_MATERIALIZE
149# undef UNIV_INLINE
150# define UNIV_INLINE	UNIV_INLINE_ORIGINAL
151#endif
152