1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1994, 2013, 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/ut0byte.ic |
21 | Utilities for byte operations |
22 | |
23 | Created 5/30/1994 Heikki Tuuri |
24 | *******************************************************************/ |
25 | |
26 | /*******************************************************//** |
27 | Creates a 64-bit integer out of two 32-bit integers. |
28 | @return created integer */ |
29 | UNIV_INLINE |
30 | ib_uint64_t |
31 | ut_ull_create( |
32 | /*==========*/ |
33 | ulint high, /*!< in: high-order 32 bits */ |
34 | ulint low) /*!< in: low-order 32 bits */ |
35 | { |
36 | ut_ad(high <= ULINT32_MASK); |
37 | ut_ad(low <= ULINT32_MASK); |
38 | return(((ib_uint64_t) high) << 32 | low); |
39 | } |
40 | |
41 | /********************************************************//** |
42 | Rounds a 64-bit integer downward to a multiple of a power of 2. |
43 | @return rounded value */ |
44 | UNIV_INLINE |
45 | ib_uint64_t |
46 | ut_uint64_align_down( |
47 | /*=================*/ |
48 | ib_uint64_t n, /*!< in: number to be rounded */ |
49 | ulint align_no) /*!< in: align by this number |
50 | which must be a power of 2 */ |
51 | { |
52 | ut_ad(align_no > 0); |
53 | ut_ad(ut_is_2pow(align_no)); |
54 | |
55 | return(n & ~((ib_uint64_t) align_no - 1)); |
56 | } |
57 | |
58 | /********************************************************//** |
59 | Rounds ib_uint64_t upward to a multiple of a power of 2. |
60 | @return rounded value */ |
61 | UNIV_INLINE |
62 | ib_uint64_t |
63 | ut_uint64_align_up( |
64 | /*===============*/ |
65 | ib_uint64_t n, /*!< in: number to be rounded */ |
66 | ulint align_no) /*!< in: align by this number |
67 | which must be a power of 2 */ |
68 | { |
69 | ib_uint64_t align_1 = (ib_uint64_t) align_no - 1; |
70 | |
71 | ut_ad(align_no > 0); |
72 | ut_ad(ut_is_2pow(align_no)); |
73 | |
74 | return((n + align_1) & ~align_1); |
75 | } |
76 | |
77 | /*********************************************************//** |
78 | The following function rounds up a pointer to the nearest aligned address. |
79 | @return aligned pointer */ |
80 | UNIV_INLINE |
81 | void* |
82 | ut_align( |
83 | /*=====*/ |
84 | const void* ptr, /*!< in: pointer */ |
85 | ulint align_no) /*!< in: align by this number */ |
86 | { |
87 | ut_ad(align_no > 0); |
88 | ut_ad(((align_no - 1) & align_no) == 0); |
89 | ut_ad(ptr); |
90 | |
91 | ut_ad(sizeof(void*) == sizeof(ulint)); |
92 | |
93 | return((void*)((((ulint) ptr) + align_no - 1) & ~(align_no - 1))); |
94 | } |
95 | |
96 | /*********************************************************//** |
97 | The following function rounds down a pointer to the nearest |
98 | aligned address. |
99 | @return aligned pointer */ |
100 | UNIV_INLINE |
101 | void* |
102 | ut_align_down( |
103 | /*==========*/ |
104 | const void* ptr, /*!< in: pointer */ |
105 | ulint align_no) /*!< in: align by this number */ |
106 | { |
107 | ut_ad(align_no > 0); |
108 | ut_ad(((align_no - 1) & align_no) == 0); |
109 | ut_ad(ptr); |
110 | |
111 | ut_ad(sizeof(void*) == sizeof(ulint)); |
112 | |
113 | return((void*)(((ulint) ptr) & ~(align_no - 1))); |
114 | } |
115 | |
116 | /*********************************************************//** |
117 | The following function computes the offset of a pointer from the nearest |
118 | aligned address. |
119 | @return distance from aligned pointer */ |
120 | UNIV_INLINE |
121 | ulint |
122 | ut_align_offset( |
123 | /*============*/ |
124 | const void* ptr, /*!< in: pointer */ |
125 | ulint align_no) /*!< in: align by this number */ |
126 | { |
127 | ut_ad(align_no > 0); |
128 | ut_ad(((align_no - 1) & align_no) == 0); |
129 | ut_ad(ptr); |
130 | |
131 | ut_ad(sizeof(void*) == sizeof(ulint)); |
132 | |
133 | return(((ulint) ptr) & (align_no - 1)); |
134 | } |
135 | |
136 | /*****************************************************************//** |
137 | Gets the nth bit of a ulint. |
138 | @return TRUE if nth bit is 1; 0th bit is defined to be the least significant */ |
139 | UNIV_INLINE |
140 | ibool |
141 | ut_bit_get_nth( |
142 | /*===========*/ |
143 | ulint a, /*!< in: ulint */ |
144 | ulint n) /*!< in: nth bit requested */ |
145 | { |
146 | ut_ad(n < 8 * sizeof(ulint)); |
147 | return(1 & (a >> n)); |
148 | } |
149 | |
150 | /*****************************************************************//** |
151 | Sets the nth bit of a ulint. |
152 | @return the ulint with the bit set as requested */ |
153 | UNIV_INLINE |
154 | ulint |
155 | ut_bit_set_nth( |
156 | /*===========*/ |
157 | ulint a, /*!< in: ulint */ |
158 | ulint n, /*!< in: nth bit requested */ |
159 | ibool val) /*!< in: value for the bit to set */ |
160 | { |
161 | ut_ad(n < 8 * sizeof(ulint)); |
162 | if (val) { |
163 | return(((ulint) 1 << n) | a); |
164 | } else { |
165 | return(~((ulint) 1 << n) & a); |
166 | } |
167 | } |
168 | |