diff --git a/.gitmodules b/.gitmodules index d7de343..47d86f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "lib/FastNoise2"] path = lib/FastNoise2 url = https://github.com/Auburn/FastNoise2 +[submodule "lib/lockfree"] + path = lib/lockfree + url = https://github.com/bhhbazinga/LockFreeLinkedList.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 2df0ff5..964a41a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.25) -project(image-gp-2 VERSION 0.0.5) +project(image-gp-2 VERSION 0.0.6) option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF) option(ENABLE_UBSAN "Enable the ub sanitizer" OFF) diff --git a/include/image_storage.h b/include/image_storage.h index 57a600f..4cdb9ec 100644 --- a/include/image_storage.h +++ b/include/image_storage.h @@ -24,6 +24,7 @@ #include #include #include +#include using image_pixel_t = float; constexpr blt::i32 IMAGE_DIMENSIONS = 256; @@ -50,87 +51,51 @@ struct image_storage_t } }; -inline std::atomic_uint64_t g_allocated_nodes = 0; -inline std::atomic_uint64_t g_deallocated_nodes = 0; - -struct atomic_node_t -{ - explicit atomic_node_t(image_storage_t* data): data(data) - { - ++g_allocated_nodes; - } - - std::atomic next = nullptr; - image_storage_t* data = nullptr; - - ~atomic_node_t() - { - ++g_deallocated_nodes; - } -}; - inline std::atomic_uint64_t g_allocated_blocks = 0; inline std::atomic_uint64_t g_deallocated_blocks = 0; -class atomic_list_t +inline std::mutex g_image_list_mutex; + +struct image_cleaner_t { -public: - atomic_list_t() = default; - - void push_back(atomic_node_t* node) + ~image_cleaner_t() { - while (true) - { - auto head = this->m_head.load(); - node->next = head; - if (this->m_head.compare_exchange_weak(head, node)) - break; - } + for (auto v : images) + delete v; } - atomic_node_t* pop_front() - { - while (true) - { - auto head = this->m_head.load(); - if (head == nullptr) - return nullptr; - if (this->m_head.compare_exchange_weak(head, head->next)) - return head; - } - } - - ~atomic_list_t() - { - while (m_head != nullptr) - delete pop_front(); - } - -private: - std::atomic m_head = nullptr; + std::vector images; }; -inline atomic_list_t g_image_list; +inline image_cleaner_t g_image_list; struct image_t { image_t() { - const auto front = g_image_list.pop_front(); - if (front) + image_storage_t* front = nullptr; { - data = front->data; - delete front; - } else + std::scoped_lock lock(g_image_list_mutex); + if (!g_image_list.images.empty()) + { + front = g_image_list.images.back(); + g_image_list.images.pop_back(); + } + } + if (front) + data = front; + else data = new image_storage_t; ++g_allocated_blocks; } void drop() { - const auto node = new atomic_node_t(data); // NOLINT + { + std::scoped_lock lock(g_image_list_mutex); + g_image_list.images.push_back(data); + } data = nullptr; - g_image_list.push_back(node); ++g_deallocated_blocks; } diff --git a/src/main.cpp b/src/main.cpp index 75f4477..a0c93c7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -120,14 +120,10 @@ void update(const blt::gfx::window_data& data) if (ImGui::Begin("Debug")) { - const auto allocated_nodes = g_allocated_nodes.load(std::memory_order_relaxed); - const auto deallocated_nodes = g_deallocated_nodes.load(std::memory_order_relaxed); const auto allocated_blocks = g_allocated_blocks.load(std::memory_order_relaxed); const auto deallocated_blocks = g_deallocated_blocks.load(std::memory_order_relaxed); - ImGui::Text("Allocated Nodes / Deallocated Nodes: (%ld / %ld) (%lf%% / %ld)", allocated_nodes, deallocated_nodes, - (static_cast(deallocated_nodes) / static_cast(allocated_nodes)) * 100.0, allocated_nodes - deallocated_nodes); - ImGui::Text("Allocated Blocks / Deallocated Blocks: (%ld / %ld) (%lf%% / %ld)", allocated_blocks, deallocated_blocks, - (static_cast(deallocated_blocks) / static_cast(allocated_blocks)) * 100.0, allocated_blocks - deallocated_blocks); + ImGui::Text("Allocated Blocks / Deallocated Blocks: (%ld / %ld) (%ld / %ld) (Total: %ld)", allocated_blocks, deallocated_blocks, + g_image_list.images.size(), allocated_blocks - deallocated_blocks, g_image_list.images.size() + (allocated_blocks - deallocated_blocks)); } ImGui::End();