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