mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 17:33:44 +01:00
8f18616ef0
and lexer files). From now on, the following Emacs cc-mode settings apply when indenting C function bodies in InnoDB: (setq c-basic-offset 8) (setq c-label-minimum-indentation 0) (add-to-list 'c-offsets-alist '(c . 0)) (add-to-list 'c-offsets-alist '(label . [0])) The indentation rules for function declarations still have not been formalized, and they must be formatted manually. Try to limit all lines to at most 79 characters (assuming TAB stops every 8 characters) by splitting lines before opening parenthesis, or at string constants. Fix some grammar mistakes in diagnostic output: match to, match with -> match found from -> found in trying rename -> trying to rename Fix an error in page_check_dir(): it said "supremum not pointed to" when the infimum was not pointed to. Enclose commented-out code snippets in #if 0 ... #endif instead of /* ... */. Add (void*) casts to some %p parameters in fprintf() calls. Try to split lines before a binary operator, not after one. (These three fixes were not made everywhere.)
397 lines
8.2 KiB
Text
397 lines
8.2 KiB
Text
/******************************************************************
|
|
Utilities for byte operations
|
|
|
|
(c) 1994, 1995 Innobase Oy
|
|
|
|
Created 5/30/1994 Heikki Tuuri
|
|
*******************************************************************/
|
|
|
|
/***********************************************************
|
|
Creates a 64-bit dulint out of two ulints. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_create(
|
|
/*=============*/
|
|
/* out: created dulint */
|
|
ulint high, /* in: high-order 32 bits */
|
|
ulint low) /* in: low-order 32 bits */
|
|
{
|
|
dulint res;
|
|
|
|
ut_ad(high <= 0xFFFFFFFF);
|
|
ut_ad(low <= 0xFFFFFFFF);
|
|
|
|
res.high = high;
|
|
res.low = low;
|
|
|
|
return(res);
|
|
}
|
|
|
|
/***********************************************************
|
|
Gets the high-order 32 bits of a dulint. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_dulint_get_high(
|
|
/*===============*/
|
|
/* out: 32 bits in ulint */
|
|
dulint d) /* in: dulint */
|
|
{
|
|
return(d.high);
|
|
}
|
|
|
|
/***********************************************************
|
|
Gets the low-order 32 bits of a dulint. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_dulint_get_low(
|
|
/*==============*/
|
|
/* out: 32 bits in ulint */
|
|
dulint d) /* in: dulint */
|
|
{
|
|
return(d.low);
|
|
}
|
|
|
|
/***********************************************************
|
|
Converts a dulint (a struct of 2 ulints) to ib_longlong, which is a 64-bit
|
|
integer type. */
|
|
UNIV_INLINE
|
|
ib_longlong
|
|
ut_conv_dulint_to_longlong(
|
|
/*=======================*/
|
|
/* out: value in ib_longlong type */
|
|
dulint d) /* in: dulint */
|
|
{
|
|
return((ib_longlong)d.low
|
|
+ (((ib_longlong)d.high) << 32));
|
|
}
|
|
|
|
/***********************************************************
|
|
Tests if a dulint is zero. */
|
|
UNIV_INLINE
|
|
ibool
|
|
ut_dulint_is_zero(
|
|
/*==============*/
|
|
/* out: TRUE if zero */
|
|
dulint a) /* in: dulint */
|
|
{
|
|
if ((a.low == 0) && (a.high == 0)) {
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
/***********************************************************
|
|
Compares two dulints. */
|
|
UNIV_INLINE
|
|
int
|
|
ut_dulint_cmp(
|
|
/*==========*/
|
|
/* out: -1 if a < b, 0 if a == b,
|
|
1 if a > b */
|
|
dulint a, /* in: dulint */
|
|
dulint b) /* in: dulint */
|
|
{
|
|
if (a.high > b.high) {
|
|
return(1);
|
|
} else if (a.high < b.high) {
|
|
return(-1);
|
|
} else if (a.low > b.low) {
|
|
return(1);
|
|
} else if (a.low < b.low) {
|
|
return(-1);
|
|
} else {
|
|
return(0);
|
|
}
|
|
}
|
|
|
|
/***********************************************************
|
|
Calculates the max of two dulints. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_get_max(
|
|
/*==============*/
|
|
/* out: max(a, b) */
|
|
dulint a, /* in: dulint */
|
|
dulint b) /* in: dulint */
|
|
{
|
|
if (ut_dulint_cmp(a, b) > 0) {
|
|
|
|
return(a);
|
|
}
|
|
|
|
return(b);
|
|
}
|
|
|
|
/***********************************************************
|
|
Calculates the min of two dulints. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_get_min(
|
|
/*==============*/
|
|
/* out: min(a, b) */
|
|
dulint a, /* in: dulint */
|
|
dulint b) /* in: dulint */
|
|
{
|
|
if (ut_dulint_cmp(a, b) > 0) {
|
|
|
|
return(b);
|
|
}
|
|
|
|
return(a);
|
|
}
|
|
|
|
/***********************************************************
|
|
Adds a ulint to a dulint. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_add(
|
|
/*==========*/
|
|
/* out: sum a + b */
|
|
dulint a, /* in: dulint */
|
|
ulint b) /* in: ulint */
|
|
{
|
|
if (0xFFFFFFFFUL - b >= a.low) {
|
|
a.low += b;
|
|
|
|
return(a);
|
|
}
|
|
|
|
a.low = a.low - (0xFFFFFFFFUL - b) - 1;
|
|
|
|
a.high++;
|
|
|
|
return(a);
|
|
}
|
|
|
|
/***********************************************************
|
|
Subtracts a ulint from a dulint. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_subtract(
|
|
/*===============*/
|
|
/* out: a - b */
|
|
dulint a, /* in: dulint */
|
|
ulint b) /* in: ulint, b <= a */
|
|
{
|
|
if (a.low >= b) {
|
|
a.low -= b;
|
|
|
|
return(a);
|
|
}
|
|
|
|
b -= a.low + 1;
|
|
|
|
a.low = 0xFFFFFFFFUL - b;
|
|
|
|
ut_ad(a.high > 0);
|
|
|
|
a.high--;
|
|
|
|
return(a);
|
|
}
|
|
|
|
/***********************************************************
|
|
Subtracts a dulint from another. NOTE that the difference must be positive
|
|
and smaller that 4G. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_dulint_minus(
|
|
/*============*/
|
|
/* out: a - b */
|
|
dulint a, /* in: dulint; NOTE a must be >= b and at most
|
|
2 to power 32 - 1 greater */
|
|
dulint b) /* in: dulint */
|
|
{
|
|
ulint diff;
|
|
|
|
if (a.high == b.high) {
|
|
ut_ad(a.low >= b.low);
|
|
|
|
return(a.low - b.low);
|
|
}
|
|
|
|
ut_ad(a.high == b.high + 1);
|
|
|
|
diff = (ulint)(0xFFFFFFFFUL - b.low);
|
|
diff += 1 + a.low;
|
|
|
|
ut_ad(diff > a.low);
|
|
|
|
return(diff);
|
|
}
|
|
|
|
/************************************************************
|
|
Rounds a dulint downward to a multiple of a power of 2. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_align_down(
|
|
/*=================*/
|
|
/* out: rounded value */
|
|
dulint n, /* in: number to be rounded */
|
|
ulint align_no) /* in: align by this number which must be a
|
|
power of 2 */
|
|
{
|
|
ulint low, high;
|
|
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
|
|
low = ut_dulint_get_low(n);
|
|
high = ut_dulint_get_high(n);
|
|
|
|
low = low & ~(align_no - 1);
|
|
|
|
return(ut_dulint_create(high, low));
|
|
}
|
|
|
|
/************************************************************
|
|
Rounds a dulint upward to a multiple of a power of 2. */
|
|
UNIV_INLINE
|
|
dulint
|
|
ut_dulint_align_up(
|
|
/*===============*/
|
|
/* out: rounded value */
|
|
dulint n, /* in: number to be rounded */
|
|
ulint align_no) /* in: align by this number which must be a
|
|
power of 2 */
|
|
{
|
|
return(ut_dulint_align_down(ut_dulint_add(n, align_no - 1), align_no));
|
|
}
|
|
|
|
/************************************************************
|
|
The following function calculates the value of an integer n rounded
|
|
to the least product of align_no which is >= n. align_no
|
|
has to be a power of 2. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_calc_align(
|
|
/*==========*/
|
|
/* out: rounded value */
|
|
ulint n, /* in: number to be rounded */
|
|
ulint align_no) /* in: align by this number */
|
|
{
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
|
|
return((n + align_no - 1) & ~(align_no - 1));
|
|
}
|
|
|
|
/*************************************************************
|
|
The following function rounds up a pointer to the nearest aligned address. */
|
|
UNIV_INLINE
|
|
void*
|
|
ut_align(
|
|
/*=====*/
|
|
/* out: aligned pointer */
|
|
void* ptr, /* in: pointer */
|
|
ulint align_no) /* in: align by this number */
|
|
{
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
ut_ad(ptr);
|
|
|
|
ut_ad(sizeof(void*) == sizeof(ulint));
|
|
|
|
return((void*)((((ulint)ptr) + align_no - 1) & ~(align_no - 1)));
|
|
}
|
|
|
|
/************************************************************
|
|
The following function calculates the value of an integer n rounded
|
|
to the biggest product of align_no which is <= n. align_no has to be a
|
|
power of 2. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_calc_align_down(
|
|
/*===============*/
|
|
/* out: rounded value */
|
|
ulint n, /* in: number to be rounded */
|
|
ulint align_no) /* in: align by this number */
|
|
{
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
|
|
return(n & ~(align_no - 1));
|
|
}
|
|
|
|
/*************************************************************
|
|
The following function rounds down a pointer to the nearest
|
|
aligned address. */
|
|
UNIV_INLINE
|
|
void*
|
|
ut_align_down(
|
|
/*==========*/
|
|
/* out: aligned pointer */
|
|
void* ptr, /* in: pointer */
|
|
ulint align_no) /* in: align by this number */
|
|
{
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
ut_ad(ptr);
|
|
|
|
ut_ad(sizeof(void*) == sizeof(ulint));
|
|
|
|
return((void*)((((ulint)ptr)) & ~(align_no - 1)));
|
|
}
|
|
|
|
/*************************************************************
|
|
The following function computes the offset of a pointer from the nearest
|
|
aligned address. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_align_offset(
|
|
/*============*/
|
|
/* out: distance from
|
|
aligned pointer */
|
|
const void* ptr, /* in: pointer */
|
|
ulint align_no) /* in: align by this number */
|
|
{
|
|
ut_ad(align_no > 0);
|
|
ut_ad(((align_no - 1) & align_no) == 0);
|
|
ut_ad(ptr);
|
|
|
|
ut_ad(sizeof(void*) == sizeof(ulint));
|
|
|
|
return(((ulint)ptr) & (align_no - 1));
|
|
}
|
|
|
|
/*********************************************************************
|
|
Gets the nth bit of a ulint. */
|
|
UNIV_INLINE
|
|
ibool
|
|
ut_bit_get_nth(
|
|
/*===========*/
|
|
/* out: TRUE if nth bit is 1; 0th bit is defined to
|
|
be the least significant */
|
|
ulint a, /* in: ulint */
|
|
ulint n) /* in: nth bit requested */
|
|
{
|
|
ut_ad(n < 8 * sizeof(ulint));
|
|
#if TRUE != 1
|
|
# error "TRUE != 1"
|
|
#endif
|
|
return(1 & (a >> n));
|
|
}
|
|
|
|
/*********************************************************************
|
|
Sets the nth bit of a ulint. */
|
|
UNIV_INLINE
|
|
ulint
|
|
ut_bit_set_nth(
|
|
/*===========*/
|
|
/* out: the ulint with the bit set as requested */
|
|
ulint a, /* in: ulint */
|
|
ulint n, /* in: nth bit requested */
|
|
ibool val) /* in: value for the bit to set */
|
|
{
|
|
ut_ad(n < 8 * sizeof(ulint));
|
|
#if TRUE != 1
|
|
# error "TRUE != 1"
|
|
#endif
|
|
if (val) {
|
|
return((1 << n) | a);
|
|
} else {
|
|
return(~(1 << n) & a);
|
|
}
|
|
}
|