fix leaks

thread
Brett 2024-07-16 21:56:21 -04:00
parent 2ca69ae953
commit 45db2acb11
4 changed files with 39 additions and 15 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.25) cmake_minimum_required(VERSION 3.25)
project(blt-gp VERSION 0.0.86) project(blt-gp VERSION 0.0.87)
include(CTest) include(CTest)

View File

@ -491,6 +491,7 @@ namespace blt::gp
{ {
thread_helper.lifetime_over = true; thread_helper.lifetime_over = true;
thread_helper.barrier.notify_all(); thread_helper.barrier.notify_all();
thread_helper.thread_function_condition.notify_all();
for (auto& thread : thread_helper.threads) for (auto& thread : thread_helper.threads)
{ {
if (thread->joinable()) if (thread->joinable())

View File

@ -206,10 +206,11 @@ namespace blt::gp
using NO_REF_T = std::remove_cv_t<std::remove_reference_t<T>>; using NO_REF_T = std::remove_cv_t<std::remove_reference_t<T>>;
static_assert(std::is_trivially_copyable_v<NO_REF_T> && "Type must be bitwise copyable!"); static_assert(std::is_trivially_copyable_v<NO_REF_T> && "Type must be bitwise copyable!");
constexpr static auto TYPE_SIZE = aligned_size<NO_REF_T>(); constexpr static auto TYPE_SIZE = aligned_size<NO_REF_T>();
if (head == nullptr)
while (head->used_bytes_in_block() == 0 && move_back());
if (empty())
throw std::runtime_error("Silly boi the stack is empty!"); throw std::runtime_error("Silly boi the stack is empty!");
if (head->used_bytes_in_block() == 0)
move_back();
if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(aligned_size<NO_REF_T>())) if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(aligned_size<NO_REF_T>()))
throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string( throw std::runtime_error((std::string("Mismatched Types! Not enough space left in block! Bytes: ") += std::to_string(
head->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(NO_REF_T))).c_str()); head->used_bytes_in_block()) += " Size: " + std::to_string(sizeof(NO_REF_T))).c_str());
@ -298,10 +299,10 @@ namespace blt::gp
*/ */
void transfer_bytes(stack_allocator& to, blt::size_t bytes) void transfer_bytes(stack_allocator& to, blt::size_t bytes)
{ {
while (!empty() && head->used_bytes_in_block() == 0) while (head->used_bytes_in_block() == 0 && move_back());
move_back();
if (empty()) if (empty())
throw std::runtime_error("This stack is empty!"); throw std::runtime_error("This stack is empty!");
if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(bytes)) if (head->used_bytes_in_block() < static_cast<blt::ptrdiff_t>(bytes))
BLT_ABORT(("This stack doesn't contain enough data for this type! " + std::to_string(head->used_bytes_in_block()) + " / " + BLT_ABORT(("This stack doesn't contain enough data for this type! " + std::to_string(head->used_bytes_in_block()) + " / " +
std::to_string(bytes) + " This is an invalid runtime state!").c_str()); std::to_string(bytes) + " This is an invalid runtime state!").c_str());
@ -318,7 +319,7 @@ namespace blt::gp
{ {
blt::size_t offset = 0; blt::size_t offset = 0;
((from < NO_REF_T < Args >> (offset).~NO_REF_T<Args>(), offset += stack_allocator::aligned_size<NO_REF_T < Args>> ((from<NO_REF_T<Args >>(offset).~NO_REF_T<Args>(), offset += stack_allocator::aligned_size<NO_REF_T<Args>>
()), ...); ()), ...);
} }
@ -418,6 +419,16 @@ namespace blt::gp
~stack_allocator() ~stack_allocator()
{ {
free_chain(head); free_chain(head);
if (head != nullptr)
{
auto blk = head->metadata.next;
while (blk != nullptr)
{
auto ptr = blk;
blk = blk->metadata.next;
std::free(ptr);
}
}
} }
template<typename T> template<typename T>
@ -480,7 +491,7 @@ namespace blt::gp
template<typename T> template<typename T>
void* allocate_bytes() void* allocate_bytes()
{ {
return allocate_bytes(sizeof(NO_REF_T < T > )); return allocate_bytes(sizeof(NO_REF_T<T>));
} }
void* allocate_bytes(blt::size_t size) void* allocate_bytes(blt::size_t size)
@ -488,13 +499,16 @@ namespace blt::gp
auto ptr = get_aligned_pointer(size); auto ptr = get_aligned_pointer(size);
if (ptr == nullptr) if (ptr == nullptr)
{ {
if (head != nullptr && head->metadata.next != nullptr) while (head != nullptr && head->metadata.next != nullptr)
{ {
head = head->metadata.next; head = head->metadata.next;
if (head != nullptr) if (head != nullptr)
head->reset(); head->reset();
} else if (head->remaining_bytes_in_block() >= static_cast<blt::ptrdiff_t>(size))
push_block(aligned_size(size)); break;
}
if (head == nullptr || head->remaining_bytes_in_block() < static_cast<blt::ptrdiff_t>(size))
push_block(aligned_size(size) + sizeof(typename block::block_metadata_t));
} }
ptr = get_aligned_pointer(size); ptr = get_aligned_pointer(size);
if (ptr == nullptr) if (ptr == nullptr)
@ -532,7 +546,7 @@ namespace blt::gp
static block* allocate_block(blt::size_t bytes) static block* allocate_block(blt::size_t bytes)
{ {
auto size = to_nearest_page_size(bytes + sizeof(typename block::block_metadata_t)); auto size = to_nearest_page_size(bytes);
auto* data = std::aligned_alloc(PAGE_SIZE, size); auto* data = std::aligned_alloc(PAGE_SIZE, size);
//auto* data = get_allocator().allocate(size); //auto* data = get_allocator().allocate(size);
new(data) block{size}; new(data) block{size};
@ -550,12 +564,16 @@ namespace blt::gp
} }
} }
inline void move_back() inline bool move_back()
{ {
auto old = head; auto old = head;
head = head->metadata.prev; head = head->metadata.prev;
if (head == nullptr) if (head == nullptr)
{
head = old; head = old;
return false;
}
return true;
//free_chain(old); //free_chain(old);
// required to prevent silly memory :3 // required to prevent silly memory :3
// if (head != nullptr) // if (head != nullptr)

View File

@ -64,7 +64,12 @@ namespace blt::gp
if (execution_function == nullptr) if (execution_function == nullptr)
{ {
std::unique_lock lock(thread_helper.thread_function_control); std::unique_lock lock(thread_helper.thread_function_control);
thread_helper.thread_function_condition.wait(lock, [this]() { return thread_execution_service != nullptr; }); while (thread_execution_service == nullptr)
{
thread_helper.thread_function_condition.wait(lock);
if (should_thread_terminate())
return;
}
execution_function = thread_execution_service.load(std::memory_order_acquire); execution_function = thread_execution_service.load(std::memory_order_acquire);
} }
if (execution_function != nullptr) if (execution_function != nullptr)