1 /*****************************************************************************
2 
3 Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2019, 2020, MariaDB Corporation.
5 
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free Software
8 Foundation; version 2 of the License.
9 
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
17 
18 *****************************************************************************/
19 
20 /******************************************************************//**
21 @file include/ut0byte.h
22 Utilities for byte operations
23 
24 Created 1/20/1994 Heikki Tuuri
25 ***********************************************************************/
26 
27 #ifndef ut0byte_h
28 #define ut0byte_h
29 
30 #include "univ.i"
31 
32 /*******************************************************//**
33 Creates a 64-bit integer out of two 32-bit integers.
34 @return created integer */
35 UNIV_INLINE
36 ib_uint64_t
37 ut_ull_create(
38 /*==========*/
39 	ulint	high,	/*!< in: high-order 32 bits */
40 	ulint	low)	/*!< in: low-order 32 bits */
41 	MY_ATTRIBUTE((const));
42 
43 /********************************************************//**
44 Rounds a 64-bit integer downward to a multiple of a power of 2.
45 @return rounded value */
46 UNIV_INLINE
47 ib_uint64_t
48 ut_uint64_align_down(
49 /*=================*/
50 	ib_uint64_t	 n,		/*!< in: number to be rounded */
51 	ulint		 align_no);	/*!< in: align by this number
52 					which must be a power of 2 */
53 /********************************************************//**
54 Rounds ib_uint64_t upward to a multiple of a power of 2.
55 @return rounded value */
56 UNIV_INLINE
57 ib_uint64_t
58 ut_uint64_align_up(
59 /*===============*/
60 	ib_uint64_t	 n,		/*!< in: number to be rounded */
61 	ulint		 align_no);	/*!< in: align by this number
62 					which must be a power of 2 */
63 /** Round down a pointer to the nearest aligned address.
64 @param ptr        pointer
65 @param alignment  a power of 2
66 @return aligned pointer */
ut_align_down(void * ptr,size_t alignment)67 static inline void *ut_align_down(void *ptr, size_t alignment)
68 {
69   ut_ad(alignment > 0);
70   ut_ad(ut_is_2pow(alignment));
71   ut_ad(ptr);
72   static_assert(sizeof ptr == sizeof(size_t), "compatibility");
73 
74   return reinterpret_cast<void*>(reinterpret_cast<size_t>(ptr) &
75                                  ~(alignment - 1));
76 }
77 
ut_align_down(const void * ptr,size_t alignment)78 static inline const void *ut_align_down(const void *ptr, size_t alignment)
79 {
80   return ut_align_down(const_cast<void*>(ptr), alignment);
81 }
82 
83 /** Compute the offset of a pointer from the nearest aligned address.
84 @param ptr        pointer
85 @param alignment  a power of 2
86 @return distance from aligned pointer */
ut_align_offset(const void * ptr,size_t alignment)87 inline size_t ut_align_offset(const void *ptr, size_t alignment)
88 {
89   ut_ad(alignment > 0);
90   ut_ad(ut_is_2pow(alignment));
91   ut_ad(ptr);
92   return reinterpret_cast<size_t>(ptr) & (alignment - 1);
93 }
94 
95 /*****************************************************************//**
96 Gets the nth bit of a ulint.
97 @return TRUE if nth bit is 1; 0th bit is defined to be the least significant */
98 UNIV_INLINE
99 ibool
100 ut_bit_get_nth(
101 /*===========*/
102 	ulint	a,	/*!< in: ulint */
103 	ulint	n);	/*!< in: nth bit requested */
104 /*****************************************************************//**
105 Sets the nth bit of a ulint.
106 @return the ulint with the bit set as requested */
107 UNIV_INLINE
108 ulint
109 ut_bit_set_nth(
110 /*===========*/
111 	ulint	a,	/*!< in: ulint */
112 	ulint	n,	/*!< in: nth bit requested */
113 	ibool	val);	/*!< in: value for the bit to set */
114 
115 #include "ut0byte.inl"
116 
117 #endif
118