mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-08-17 23:55:04 +00:00
New Features - Added policy-based memory allocation APIs with capability flags and optional alignment: `memory_alloc_with_policy`, `memory_realloc_with_policy`, `memory_calloc_with_policy`, and `memory_free`. - Switched heap memory reporting to `memory_print_stats`. Bug Fixes - Improved allocation robustness with capability fallback behavior. - Added overflow-safe handling for aligned zero-initialized allocations. - Tightened const-correctness for generated device-tree device arrays. Tests - Added unit tests for default policy, alignment, zero-initialization, realloc preservation, freeing, and memory stats reporting.
84 lines
2.4 KiB
C++
84 lines
2.4 KiB
C++
#include "doctest.h"
|
|
#include <tactility/memory.h>
|
|
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
|
|
TEST_CASE("MEMORY_POLICY_DEFAULT should have no requirements") {
|
|
CHECK_EQ(MEMORY_POLICY_DEFAULT.required, 0);
|
|
CHECK_EQ(MEMORY_POLICY_DEFAULT.desired, 0);
|
|
CHECK_EQ(MEMORY_POLICY_DEFAULT.alignment, 0);
|
|
}
|
|
|
|
TEST_CASE("memory_alloc should return usable memory") {
|
|
void* ptr = memory_alloc(64);
|
|
REQUIRE_NE(ptr, nullptr);
|
|
memset(ptr, 0xAB, 64);
|
|
CHECK_EQ(static_cast<uint8_t*>(ptr)[0], 0xAB);
|
|
CHECK_EQ(static_cast<uint8_t*>(ptr)[63], 0xAB);
|
|
memory_free(ptr);
|
|
}
|
|
|
|
TEST_CASE("memory_calloc should zero-initialize memory") {
|
|
auto* ptr = static_cast<uint8_t*>(memory_calloc(16, sizeof(uint8_t)));
|
|
REQUIRE_NE(ptr, nullptr);
|
|
for (size_t i = 0; i < 16; i++) {
|
|
CHECK_EQ(ptr[i], 0);
|
|
}
|
|
memory_free(ptr);
|
|
}
|
|
|
|
TEST_CASE("memory_realloc should preserve contents when growing") {
|
|
auto* ptr = static_cast<uint8_t*>(memory_alloc(8));
|
|
REQUIRE_NE(ptr, nullptr);
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
ptr[i] = i;
|
|
}
|
|
|
|
auto* grown = static_cast<uint8_t*>(memory_realloc(ptr, 32));
|
|
REQUIRE_NE(grown, nullptr);
|
|
for (uint8_t i = 0; i < 8; i++) {
|
|
CHECK_EQ(grown[i], i);
|
|
}
|
|
|
|
memory_free(grown);
|
|
}
|
|
|
|
TEST_CASE("memory_realloc with a NULL pointer should behave like an allocation") {
|
|
void* ptr = memory_realloc(nullptr, 32);
|
|
REQUIRE_NE(ptr, nullptr);
|
|
memset(ptr, 0, 32);
|
|
memory_free(ptr);
|
|
}
|
|
|
|
TEST_CASE("memory_free with a NULL pointer should be a no-op") {
|
|
memory_free(nullptr);
|
|
}
|
|
|
|
TEST_CASE("memory_alloc_with_policy should honor a power-of-2 alignment") {
|
|
MemoryPolicy policy = MEMORY_POLICY_DEFAULT;
|
|
policy.alignment = 64;
|
|
|
|
void* ptr = memory_alloc_with_policy(128, &policy);
|
|
REQUIRE_NE(ptr, nullptr);
|
|
CHECK_EQ(reinterpret_cast<uintptr_t>(ptr) % 64, 0);
|
|
memory_free(ptr);
|
|
}
|
|
|
|
TEST_CASE("memory_calloc_with_policy should honor alignment and zero-initialize") {
|
|
MemoryPolicy policy = MEMORY_POLICY_DEFAULT;
|
|
policy.alignment = 32;
|
|
|
|
auto* ptr = static_cast<uint8_t*>(memory_calloc_with_policy(8, sizeof(uint32_t), &policy));
|
|
REQUIRE_NE(ptr, nullptr);
|
|
CHECK_EQ(reinterpret_cast<uintptr_t>(ptr) % 32, 0);
|
|
for (size_t i = 0; i < 8 * sizeof(uint32_t); i++) {
|
|
CHECK_EQ(ptr[i], 0);
|
|
}
|
|
memory_free(ptr);
|
|
}
|
|
|
|
TEST_CASE("memory_print_stats should not crash") {
|
|
memory_print_stats();
|
|
}
|