1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | |
5 | This program is free software; you can redistribute it and/or modify it under |
6 | the terms of the GNU General Public License as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /**************************************************//** |
20 | @file include/buf0buddy.ic |
21 | Binary buddy allocator for compressed pages |
22 | |
23 | Created 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 | /**********************************************************************//** |
35 | Allocate a block. The thread calling this function must hold |
36 | buf_pool->mutex and must not hold buf_pool->zip_mutex or any block->mutex. |
37 | The buf_pool_mutex may be released and reacquired. |
38 | @return allocated block, never NULL */ |
39 | void* |
40 | buf_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 | /**********************************************************************//** |
53 | Deallocate a block. */ |
54 | void |
55 | buf_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 | /**********************************************************************//** |
65 | Get the index of buf_pool->zip_free[] for a given block size. |
66 | @return index of buf_pool->zip_free[], or BUF_BUDDY_SIZES */ |
67 | UNIV_INLINE |
68 | ulint |
69 | buf_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 | /**********************************************************************//** |
86 | Allocate a block. The thread calling this function must hold |
87 | buf_pool->mutex and must not hold buf_pool->zip_mutex or any |
88 | block->mutex. The buf_pool->mutex may be released and reacquired. |
89 | This function should only be used for allocating compressed page frames. |
90 | @return allocated block, never NULL */ |
91 | UNIV_INLINE |
92 | byte* |
93 | buf_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 | /**********************************************************************//** |
116 | Deallocate a block. */ |
117 | UNIV_INLINE |
118 | void |
119 | buf_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 | |