Skip to content

Commit

Permalink
util/RoundPowerOfTwo: new library
Browse files Browse the repository at this point in the history
  • Loading branch information
MaxKellermann committed May 13, 2024
1 parent 64c291b commit 416f65f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/util/HugeAllocator.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "HugeAllocator.hxx"
#include "system/VmaName.hxx"
#include "util/RoundPowerOfTwo.hxx"

#include <new>

Expand All @@ -26,8 +27,7 @@ AlignToPageSize(size_t size) noexcept
if (page_size <= 0)
return size;

size_t ps(page_size);
return (size + ps - 1) / ps * ps;
return RoundUpToPowerOfTwo(size, static_cast<std::size_t>(page_size));
}

std::span<std::byte>
Expand Down
50 changes: 50 additions & 0 deletions src/util/RoundPowerOfTwo.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright CM4all GmbH
// author: Max Kellermann <[email protected]>

#pragma once

#include <concepts>

template<std::unsigned_integral T>
constexpr T
RoundUpToPowerOfTwo(T value) noexcept
{
if (value <= 0)
return 1;

--value;

for (unsigned bits = 1; bits < sizeof(T) * 8; bits <<= 1)
value |= value >> bits;

++value;

return value;
}

static_assert(RoundUpToPowerOfTwo(0U) == 1U);
static_assert(RoundUpToPowerOfTwo(2U) == 2U);
static_assert(RoundUpToPowerOfTwo(3U) == 4U);
static_assert(RoundUpToPowerOfTwo(4U) == 4U);
static_assert(RoundUpToPowerOfTwo(5U) == 8U);
static_assert(RoundUpToPowerOfTwo(0x7fffU) == 0x8000U);
static_assert(RoundUpToPowerOfTwo(0x7ffffU) == 0x80000U);
static_assert(RoundUpToPowerOfTwo(0x1000000000000000ULL) == 0x1000000000000000ULL);
static_assert(RoundUpToPowerOfTwo(0x1fffffffffffffffULL) == 0x2000000000000000ULL);
static_assert(RoundUpToPowerOfTwo(0x7fffffffffffffffULL) == 0x8000000000000000ULL);
static_assert(RoundUpToPowerOfTwo(0x8000000000000000ULL) == 0x8000000000000000ULL);

template<std::unsigned_integral T>
constexpr T
RoundUpToPowerOfTwo(T value, T power_of_two) noexcept
{
return ((value - 1) | (power_of_two - 1)) + 1;
}

template<std::unsigned_integral T>
constexpr T
RoundDownToPowerOfTwo(T value, T power_of_two) noexcept
{
return value & ~(power_of_two - 1);
}

0 comments on commit 416f65f

Please sign in to comment.