blob: 7d124cc95eddf4ab5a4df360fe6853769d5224f1 [file] [log] [blame]
// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "pw_allocator/typed_pool.h"
#include <array>
#include <cstddef>
#include <cstdint>
#include "pw_allocator/allocator.h"
#include "pw_bytes/alignment.h"
#include "pw_unit_test/framework.h"
namespace pw::allocator {
namespace {
class TypedPoolTest : public ::testing::Test {
protected:
struct U32 {
std::byte bytes[4];
};
static constexpr size_t kNumU32s = 4;
TypedPool<U32>::Buffer<kNumU32s> buffer_;
};
TEST_F(TypedPoolTest, LayoutNeeded) {
EXPECT_EQ(TypedPool<std::byte[1]>::SizeNeeded(1), sizeof(void*));
EXPECT_EQ(TypedPool<std::byte[16]>::SizeNeeded(1), 16U);
EXPECT_EQ(TypedPool<std::byte[1]>::SizeNeeded(10), sizeof(void*) * 10);
EXPECT_EQ(TypedPool<std::byte[16]>::SizeNeeded(10), 160U);
EXPECT_EQ(TypedPool<std::byte[1]>::AlignmentNeeded(), alignof(void*));
struct HighlyAligned {
alignas(64) std::byte data[128];
};
EXPECT_EQ(TypedPool<HighlyAligned>::AlignmentNeeded(), 64U);
}
TEST_F(TypedPoolTest, AllocateDeallocate) {
TypedPool<U32> allocator(buffer_);
void* ptr = allocator.Allocate();
ASSERT_NE(ptr, nullptr);
allocator.Deallocate(ptr);
}
TEST_F(TypedPoolTest, MakeUnique) {
TypedPool<U32> allocator(buffer_);
// Should be able allocate `kNumU32s`.
std::array<UniquePtr<U32>, kNumU32s> ptrs;
for (size_t i = 0; i < kNumU32s; ++i) {
ptrs[i] = allocator.MakeUnique();
ASSERT_NE(ptrs[i], nullptr);
}
// Should be exhausted.
EXPECT_EQ(allocator.MakeUnique(), nullptr);
// Should be able to drop the ptrs and allocate `kNumU32s` more.
for (size_t i = 0; i < kNumU32s; ++i) {
ptrs[i] = UniquePtr<U32>();
}
for (size_t i = 0; i < kNumU32s; ++i) {
ptrs[i] = allocator.MakeUnique();
ASSERT_NE(ptrs[i], nullptr);
}
}
} // namespace
} // namespace pw::allocator