补充提交
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
#include <atomic>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory_resource>
|
||||
#include <stdexcept>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "../Renderive/base/Memory.h"
|
||||
namespace {
|
||||
struct Callback_State {
|
||||
std::atomic<std::uint64_t> allocation_count{};
|
||||
std::atomic<std::uint64_t> deallocation_count{};
|
||||
std::atomic_bool alignment_error{};
|
||||
std::atomic_bool deallocated_off_main_thread{};
|
||||
std::thread::id main_thread;
|
||||
};
|
||||
Callback_State callback_state;
|
||||
void* callback_allocate(void* context, std::size_t size, std::size_t alignment) {
|
||||
auto* state = static_cast<Callback_State*>(context);
|
||||
void* result{};
|
||||
try {
|
||||
result = std::pmr::new_delete_resource()->allocate(size, alignment);
|
||||
}
|
||||
catch (...) {
|
||||
return nullptr;
|
||||
}
|
||||
state->allocation_count.fetch_add(1, std::memory_order_relaxed);
|
||||
if (reinterpret_cast<std::uintptr_t>(result) % alignment)
|
||||
state->alignment_error.store(true, std::memory_order_relaxed);
|
||||
return result;
|
||||
}
|
||||
void callback_deallocate(void* context, void* address, std::size_t size, std::size_t alignment) {
|
||||
auto* state = static_cast<Callback_State*>(context);
|
||||
state->deallocation_count.fetch_add(1, std::memory_order_relaxed);
|
||||
if (std::this_thread::get_id() != state->main_thread)
|
||||
state->deallocated_off_main_thread.store(true, std::memory_order_relaxed);
|
||||
std::pmr::new_delete_resource()->deallocate(address, size, alignment);
|
||||
}
|
||||
struct Payload {
|
||||
std::uint64_t value{};
|
||||
};
|
||||
struct Large_Payload {
|
||||
std::array<std::byte, 128 * 1024> data{};
|
||||
};
|
||||
}
|
||||
int main() {
|
||||
callback_state.main_thread = std::this_thread::get_id();
|
||||
renderive::Memory_Callbacks invalid_callbacks;
|
||||
invalid_callbacks.context = &callback_state;
|
||||
invalid_callbacks.allocate = callback_allocate;
|
||||
try {
|
||||
renderive::set_memory_callbacks(invalid_callbacks);
|
||||
return 1;
|
||||
}
|
||||
catch (const std::invalid_argument&) {}
|
||||
invalid_callbacks.allocate = nullptr;
|
||||
invalid_callbacks.deallocate = callback_deallocate;
|
||||
try {
|
||||
renderive::set_memory_callbacks(invalid_callbacks);
|
||||
return 2;
|
||||
}
|
||||
catch (const std::invalid_argument&) {}
|
||||
renderive::Memory_Callbacks callbacks;
|
||||
callbacks.context = &callback_state;
|
||||
callbacks.allocate = callback_allocate;
|
||||
callbacks.deallocate = callback_deallocate;
|
||||
renderive::set_memory_callbacks(callbacks);
|
||||
try {
|
||||
renderive::set_memory_callbacks(callbacks);
|
||||
return 3;
|
||||
}
|
||||
catch (const std::logic_error&) {}
|
||||
{
|
||||
std::pmr::vector<std::uint64_t> values(renderive::memory_resource());
|
||||
values.resize(8192, 11);
|
||||
auto owner = renderive::make_shared<Payload>();
|
||||
auto large_owner = renderive::make_shared<Large_Payload>();
|
||||
owner->value = values.front();
|
||||
std::thread release_thread([owner = std::move(owner), large_owner = std::move(large_owner)]() mutable {
|
||||
owner.reset();
|
||||
large_owner.reset();
|
||||
});
|
||||
release_thread.join();
|
||||
}
|
||||
renderive::release_unused_memory();
|
||||
renderive::Memory_Stats stats = renderive::memory_stats();
|
||||
if (callback_state.alignment_error.load(std::memory_order_relaxed))
|
||||
return 4;
|
||||
if (!callback_state.allocation_count.load(std::memory_order_relaxed))
|
||||
return 5;
|
||||
if (stats.upstream_allocation_count != callback_state.allocation_count.load(std::memory_order_relaxed))
|
||||
return 6;
|
||||
if (!callback_state.deallocation_count.load(std::memory_order_relaxed) || !callback_state.deallocated_off_main_thread.load(std::memory_order_relaxed))
|
||||
return 7;
|
||||
renderive::shutdown_memory();
|
||||
if (renderive::memory_stats().upstream_current_bytes)
|
||||
return 8;
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user