Skip to content

Commit

Permalink
log2_truncate(), log2_round(), log2_round_up(), round_up_to_exp2()
Browse files Browse the repository at this point in the history
  • Loading branch information
lihuiba committed Sep 25, 2024
1 parent b41b89e commit 854bc2e
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 40 deletions.
26 changes: 8 additions & 18 deletions common/io-alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ template<
size_t ALIGNMENT = 4096>
class PooledAllocator
{
constexpr static bool is_power2(size_t n) { return (n & (n-1)) == 0; }
static_assert(is_power2(ALIGNMENT), "must be 2^n");
static_assert(is_power2(MAX_ALLOCATION_SIZE), "must be 2^n");
static_assert(is_power_of_2(ALIGNMENT), "must be 2^n");
static_assert(is_power_of_2(MAX_ALLOCATION_SIZE), "must be 2^n");
static_assert(MAX_ALLOCATION_SIZE >= ALIGNMENT, "...");
const static size_t N_SLOTS = __builtin_ffsl(MAX_ALLOCATION_SIZE / 4096);
public:
Expand Down Expand Up @@ -151,7 +150,6 @@ class PooledAllocator
}

protected:
const int BASE_OFF = log2_round(ALIGNMENT);
class Slot : public IdentityPool<void, SLOT_CAPACITY>
{
public:
Expand All @@ -177,19 +175,10 @@ class PooledAllocator
}
};

static inline int log2_round(unsigned int x, bool round_up = false) {
assert(x > 0);
int ret = sizeof(x)*8 - 1 - __builtin_clz(x);
if (round_up && (1U << ret) < x)
return ret + 1;
return ret;
}

int get_slot(unsigned int x, bool round_up = false) {
int i = log2_round(x, round_up);
if (i < BASE_OFF)
return 0;
return i - BASE_OFF;
int get_slot(unsigned int x, bool round_up = true) {
auto i = round_up ? log2_round_up(x) : log2_truncate(x);
auto BASE_OFF = log2_truncate(ALIGNMENT);
return (i < BASE_OFF) ? 0 : (i - BASE_OFF);
}

Slot slots[N_SLOTS];
Expand All @@ -211,7 +200,8 @@ class PooledAllocator
size_t size = malloc_usable_size(ptr);
#endif
assert(size > 0);
slots[get_slot(size)].put(ptr);
assert(is_power_of_2(size));
slots[get_slot(size, false)].put(ptr);
return 0;
}
};
Expand Down
9 changes: 1 addition & 8 deletions common/ring.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ limitations under the License.
#include <utility>
#include <unistd.h>
#include <cstdlib>
#include <photon/common/utility.h>
#include <photon/thread/thread.h>

// RingBase exists only to reduce the size of template RingQueue
Expand All @@ -42,14 +43,6 @@ class RingBase
return m_capacity;
}

static uint32_t round_up_to_exp2(uint32_t x)
{
if (x == 0) return 1;
auto clz = __builtin_clz(x); // 'count leading zero'
uint32_t y = 1 << (31 - clz);
return (clz == 0 || y == x) ? y : y * 2;
}

int ensure_not_full()
{
while(full())
Expand Down
6 changes: 3 additions & 3 deletions common/test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,13 @@ char str[] = "2018/01/05 21:53:28|DEBUG| 2423423|test.cpp:254|virtual void LOGPe

TEST(ring, round_up_to_exp2)
{
EXPECT_EQ(RingBase::round_up_to_exp2(0), 1);
EXPECT_EQ(RingBase::round_up_to_exp2(1), 1);
EXPECT_EQ(round_up_to_exp2(0), 1);
EXPECT_EQ(round_up_to_exp2(1), 1);

uint32_t i = 2;
for (uint32_t exp2 = 2; exp2 <= (1<<25); exp2 *= 2)
for ((void)i; i <= exp2; ++i)
EXPECT_EQ(RingBase::round_up_to_exp2(i), exp2);
EXPECT_EQ(round_up_to_exp2(i), exp2);
}

int rq_step = 0;
Expand Down
8 changes: 4 additions & 4 deletions common/test/test_scalepool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,14 @@ TEST(IOAlloc, basic) {
for (auto &x:mem) {
alloc.dealloc(x);
}
while (mpool.slots[mpool.get_slot(64*1024, true)].m_size < 32) {
while (mpool.slots[mpool.get_slot(64*1024)].m_size < 32) {
photon::thread_usleep(1000);
}
while (mpool.slots[mpool.get_slot(64*1024, true)].m_size > 0) {
while (mpool.slots[mpool.get_slot(64*1024)].m_size > 0) {
photon::thread_usleep(1000 * 1000);
LOG_DEBUG(VALUE(mpool.slots[mpool.get_slot(64*1024, true)].m_size));
LOG_DEBUG(VALUE(mpool.slots[mpool.get_slot(64*1024)].m_size));
}
EXPECT_EQ(0U, mpool.slots[mpool.get_slot(64*1024, true)].m_size);
EXPECT_EQ(0U, mpool.slots[mpool.get_slot(64*1024)].m_size);
}
int main(int argc, char **argv)
{
Expand Down
32 changes: 29 additions & 3 deletions common/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,35 @@ struct is_function_pointer
#define ENABLE_IF_NOT_POINTER(T) ENABLE_IF(!IS_POINTER(T))


inline bool is_power_of_2(uint64_t x)
{
return __builtin_popcountl(x) == 1;
inline constexpr bool is_power_of_2(uint64_t x) {
return !x || __builtin_popcountl(x) == 1;
}

inline constexpr uint8_t log2_truncate(size_t x) {
assert(x > 0);
uint8_t exp = sizeof(x) * 8 - 1 - __builtin_clzl(x);
assert(x & (1UL << exp));
return exp;
}

inline constexpr uint8_t log2_round(size_t x) {
assert(x > 0);
uint8_t exp = log2_truncate(x);
assert(x & (1UL << exp));
bool carry = exp && (x & (1UL << (exp - 1)));
return exp + carry;
}

inline constexpr uint8_t log2_round_up(size_t x) {
assert(x > 0);
return (x <= 1) ? x : log2_truncate(x - 1) + 1;
}

inline size_t round_up_to_exp2(size_t x) {
if (x == 0) return 1;
uint32_t y = 1UL << log2_truncate(x);
assert(x&y);
return y << (!!(x^y));
}

template<typename INT>
Expand Down
8 changes: 4 additions & 4 deletions thread/stack-allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ class PooledStackAllocator {
};

// get_slot(length) returns first slot that larger or equal to length
static inline uint32_t get_slot(uint32_t length) {
static auto base = __builtin_clz(MIN_ALLOCATION_SIZE - 1);
auto index = __builtin_clz(length - 1);
return base > index ? base - index : 0;
uint32_t get_slot(uint32_t length) {
auto index = log2_round_up(length);
auto base = log2_truncate(MIN_ALLOCATION_SIZE);
return (index <= base) ? 0 : (index - base);
}

Slot slots[N_SLOTS];
Expand Down

0 comments on commit 854bc2e

Please sign in to comment.