Commit e7f426d2 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-19212: Replace macros with type-safe inline functions

The regression that was reported in MDEV-19212 occurred due to use
of macros that did not ensure that the arguments have compatible
types.

ut_2pow_remainder(), ut_2pow_round(), ut_calc_align(): Define as
inline function templates.

UT_CALC_ALIGN(): Define as a macro, because this is used in
compile_time_assert(). Only starting with C++11 (MariaDB 10.4)
we could define the inline functions as constexpr.
parent f120a15b
...@@ -955,7 +955,7 @@ fsp_try_extend_data_file(fil_space_t* space, fsp_header_t* header, mtr_t* mtr) ...@@ -955,7 +955,7 @@ fsp_try_extend_data_file(fil_space_t* space, fsp_header_t* header, mtr_t* mtr)
/* We ignore any fragments of a full megabyte when storing the size /* We ignore any fragments of a full megabyte when storing the size
to the space header */ to the space header */
space->size_in_header = ut_calc_align_down( space->size_in_header = ut_2pow_round(
space->size, (1024 * 1024) / page_size.physical()); space->size, (1024 * 1024) / page_size.physical());
mlog_write_ulint( mlog_write_ulint(
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2018, MariaDB Corporation. Copyright (c) 2017, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -77,7 +77,7 @@ is the maximum size for a single allocated buffer: */ ...@@ -77,7 +77,7 @@ is the maximum size for a single allocated buffer: */
/** Space needed when allocating for a user a field of length N. /** Space needed when allocating for a user a field of length N.
The space is allocated only in multiples of UNIV_MEM_ALIGNMENT. */ The space is allocated only in multiples of UNIV_MEM_ALIGNMENT. */
#define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #define MEM_SPACE_NEEDED(N) UT_CALC_ALIGN((N), UNIV_MEM_ALIGNMENT)
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
/** Macro for memory heap creation. /** Macro for memory heap creation.
...@@ -342,8 +342,8 @@ struct mem_block_info_t { ...@@ -342,8 +342,8 @@ struct mem_block_info_t {
#define MEM_FREED_BLOCK_MAGIC_N 547711122 #define MEM_FREED_BLOCK_MAGIC_N 547711122
/* Header size for a memory heap block */ /* Header size for a memory heap block */
#define MEM_BLOCK_HEADER_SIZE ut_calc_align(sizeof(mem_block_info_t),\ #define MEM_BLOCK_HEADER_SIZE UT_CALC_ALIGN(sizeof(mem_block_info_t),\
UNIV_MEM_ALIGNMENT) UNIV_MEM_ALIGNMENT)
#include "mem0mem.ic" #include "mem0mem.ic"
#endif #endif
/***************************************************************************** /*****************************************************************************
Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -165,26 +166,23 @@ Calculates fast the remainder of n/m when m is a power of two. ...@@ -165,26 +166,23 @@ Calculates fast the remainder of n/m when m is a power of two.
@param n in: numerator @param n in: numerator
@param m in: denominator, must be a power of two @param m in: denominator, must be a power of two
@return the remainder of n/m */ @return the remainder of n/m */
#define ut_2pow_remainder(n, m) ((n) & ((m) - 1)) template <typename T> inline T ut_2pow_remainder(T n, T m){return n & (m - 1);}
/*************************************************************//** /*************************************************************//**
Calculates the biggest multiple of m that is not bigger than n Calculates the biggest multiple of m that is not bigger than n
when m is a power of two. In other words, rounds n down to m * k. when m is a power of two. In other words, rounds n down to m * k.
@param n in: number to round down @param n in: number to round down
@param m in: alignment, must be a power of two @param m in: alignment, must be a power of two
@return n rounded down to the biggest possible integer multiple of m */ @return n rounded down to the biggest possible integer multiple of m */
#define ut_2pow_round(n, m) ((n) & ~((m) - 1)) template <typename T> inline T ut_2pow_round(T n, T m) { return n & ~(m - 1); }
/** Align a number down to a multiple of a power of two.
@param n in: number to round down
@param m in: alignment, must be a power of two
@return n rounded down to the biggest possible integer multiple of m */
#define ut_calc_align_down(n, m) ut_2pow_round(n, m)
/********************************************************//** /********************************************************//**
Calculates the smallest multiple of m that is not smaller than n Calculates the smallest multiple of m that is not smaller than n
when m is a power of two. In other words, rounds n up to m * k. when m is a power of two. In other words, rounds n up to m * k.
@param n in: number to round up @param n in: number to round up
@param m in: alignment, must be a power of two @param m in: alignment, must be a power of two
@return n rounded up to the smallest possible integer multiple of m */ @return n rounded up to the smallest possible integer multiple of m */
#define ut_calc_align(n, m) (((n) + ((m) - 1)) & ~((m) - 1)) #define UT_CALC_ALIGN(n, m) ((n + m - 1) & ~(m - 1))
template <typename T> inline T ut_calc_align(T n, T m)
{ return UT_CALC_ALIGN(n, m); }
/*************************************************************//** /*************************************************************//**
Calculates fast the 2-logarithm of a number, rounded upward to an Calculates fast the 2-logarithm of a number, rounded upward to an
......
...@@ -203,10 +203,8 @@ log_buffer_extend( ...@@ -203,10 +203,8 @@ log_buffer_extend(
log_sys->is_extending = true; log_sys->is_extending = true;
while (ut_calc_align_down(log_sys->buf_free, while ((log_sys->buf_free ^ log_sys->buf_next_to_write)
OS_FILE_LOG_BLOCK_SIZE) & (OS_FILE_LOG_BLOCK_SIZE - 1)) {
!= ut_calc_align_down(log_sys->buf_next_to_write,
OS_FILE_LOG_BLOCK_SIZE)) {
/* Buffer might have >1 blocks to write still. */ /* Buffer might have >1 blocks to write still. */
log_mutex_exit_all(); log_mutex_exit_all();
...@@ -215,9 +213,8 @@ log_buffer_extend( ...@@ -215,9 +213,8 @@ log_buffer_extend(
log_mutex_enter_all(); log_mutex_enter_all();
} }
move_start = ut_calc_align_down( move_start = ut_2pow_round(log_sys->buf_free,
log_sys->buf_free, ulint(OS_FILE_LOG_BLOCK_SIZE));
OS_FILE_LOG_BLOCK_SIZE);
move_end = log_sys->buf_free; move_end = log_sys->buf_free;
/* store the last log block in buffer */ /* store the last log block in buffer */
...@@ -1079,8 +1076,8 @@ log_buffer_switch() ...@@ -1079,8 +1076,8 @@ log_buffer_switch()
ut_ad(log_write_mutex_own()); ut_ad(log_write_mutex_own());
const byte* old_buf = log_sys->buf; const byte* old_buf = log_sys->buf;
ulint area_end = ut_calc_align(log_sys->buf_free, ulint area_end = ut_calc_align(
OS_FILE_LOG_BLOCK_SIZE); log_sys->buf_free, ulint(OS_FILE_LOG_BLOCK_SIZE));
if (log_sys->first_in_use) { if (log_sys->first_in_use) {
log_sys->first_in_use = false; log_sys->first_in_use = false;
...@@ -1215,8 +1212,9 @@ log_write_up_to( ...@@ -1215,8 +1212,9 @@ log_write_up_to(
start_offset = log_sys->buf_next_to_write; start_offset = log_sys->buf_next_to_write;
end_offset = log_sys->buf_free; end_offset = log_sys->buf_free;
area_start = ut_calc_align_down(start_offset, OS_FILE_LOG_BLOCK_SIZE); area_start = ut_2pow_round(start_offset,
area_end = ut_calc_align(end_offset, OS_FILE_LOG_BLOCK_SIZE); ulint(OS_FILE_LOG_BLOCK_SIZE));
area_end = ut_calc_align(end_offset, ulint(OS_FILE_LOG_BLOCK_SIZE));
ut_ad(area_end - area_start > 0); ut_ad(area_end - area_start > 0);
......
...@@ -115,10 +115,8 @@ os_mem_alloc_large( ...@@ -115,10 +115,8 @@ os_mem_alloc_large(
/* Align block size to system page size */ /* Align block size to system page size */
ut_ad(ut_is_2pow(system_info.dwPageSize)); ut_ad(ut_is_2pow(system_info.dwPageSize));
/* system_info.dwPageSize is only 32-bit. Casting to ulint is required size = *n = ut_2pow_round<ulint>(*n + (system_info.dwPageSize - 1),
on 64-bit Windows. */ system_info.dwPageSize);
size = *n = ut_2pow_round(*n + (system_info.dwPageSize - 1),
(ulint) system_info.dwPageSize);
ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE); PAGE_READWRITE);
if (!ptr) { if (!ptr) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment