diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-13 19:01:05 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-07-14 13:04:42 +0200 |
commit | 3e4a66786b4cd1b4c691d91f27cb6fdf920fe586 (patch) | |
tree | 52e188f09afb0d81d857df4bc2f335eb42230c6d | |
parent | 1250fc680050848d777bbb37aa294ad5cff20436 (diff) |
w
-rw-r--r-- | src/handle-fwd.hpp | 7 | ||||
-rw-r--r-- | src/handle-page.hpp | 9 | ||||
-rw-r--r-- | src/handle-page.inl | 30 |
3 files changed, 33 insertions, 13 deletions
diff --git a/src/handle-fwd.hpp b/src/handle-fwd.hpp index 79fa76e9..3e010f6d 100644 --- a/src/handle-fwd.hpp +++ b/src/handle-fwd.hpp @@ -13,16 +13,9 @@ struct Handle final uint32_t index = (uint32_t)-1; uint32_t counter = 0; -#if 0 - using Obj = OBJ; - static constexpr auto PageSize = PAGE_SIZE; -#endif - const OBJ& get() const; OBJ& get(); - bool operator==(const Handle& other) const noexcept; - explicit operator bool() const noexcept; private: diff --git a/src/handle-page.hpp b/src/handle-page.hpp index bf7ecdad..7afad5f8 100644 --- a/src/handle-page.hpp +++ b/src/handle-page.hpp @@ -9,7 +9,10 @@ namespace floormat::impl_handle { template<typename Obj, uint32_t PageSize> struct Item { + fm_DECLARE_DELETED_COPY_MOVE_ASSIGNMENTS(Item); + Item(); ~Item() noexcept; + union { char empty = {}; Obj object; }; Handle<Obj, PageSize> handle; uint32_t next; @@ -23,8 +26,9 @@ class Page std::array<Item<Obj, PageSize>, PageSize> storage; BitArray used_map; // todo replace with a rewrite of std::bitset uint32_t start_index; - uint32_t used_count = 0; - uint32_t first_free = (uint32_t)-1; + uint32_t used_count; + uint32_t first_free; + bool locked; static void do_deallocate(Item<Obj, PageSize>& item); @@ -43,6 +47,7 @@ public: void deallocate_all(); bool is_empty(); bool is_full(); + uint32_t use_count() const; }; } // namespace floormat::impl_handle diff --git a/src/handle-page.inl b/src/handle-page.inl index 70837e0c..dbf8dbcc 100644 --- a/src/handle-page.inl +++ b/src/handle-page.inl @@ -6,6 +6,9 @@ namespace floormat::impl_handle { template<typename Obj, uint32_t PageSize> +Item<Obj, PageSize>::Item() = default; + +template<typename Obj, uint32_t PageSize> Item<Obj, PageSize>::~Item() noexcept {} @@ -25,9 +28,11 @@ template<typename Obj, uint32_t PageSize> Page<Obj, PageSize>::Page(uint32_t start_index): used_map{ValueInit, PageSize}, start_index{start_index}, - first_free{start_index} + used_count{0}, + first_free{start_index}, + locked{false} { - fm_assert(size_t{start_index} + size_t{PageSize} <= size_t{1u<<31} && start_index + PageSize > start_index); + fm_assert(start_index + PageSize > start_index); auto val = start_index; for (auto i = 0u; i < PageSize; i++) { @@ -44,6 +49,8 @@ requires requires (Xs&&... xs) { } Item<Obj, PageSize>& Page<Obj, PageSize>::allocate(Xs&&... xs) { + fm_assert(!locked); + locked = true; fm_assert(used_count < PageSize); auto first_freeʹ = first_free - start_index; fm_debug_assert(first_freeʹ < PageSize); @@ -53,12 +60,15 @@ Item<Obj, PageSize>& Page<Obj, PageSize>::allocate(Xs&&... xs) used_count++; used_map.set(first_freeʹ, true); new (&item.object) Obj{ forward<Xs>(xs)... }; + locked = false; return item; } template<typename Obj, uint32_t PageSize> void Page<Obj, PageSize>::deallocate(Handle<Obj, PageSize> obj) { + fm_assert(!locked); + locked = true; auto index = obj.index - start_index; fm_debug_assert(index < PageSize); fm_assert(used_map[index]); @@ -67,18 +77,21 @@ void Page<Obj, PageSize>::deallocate(Handle<Obj, PageSize> obj) auto& item = storage[index]; auto ctr = item.handle.counter++; if (ctr == (uint32_t)-1) [[unlikely]] - Debug{} << "counter" << FM_PRETTY_FUNCTION << "overflowed"; + fm_debug("counter %s overflowed", FM_PRETTY_FUNCTION); fm_assert(obj.counter == ctr); item.next = first_free; first_free = obj.index; used_count--; used_map.set(index, false); do_deallocate(item); + locked = false; } template<typename Obj, uint32_t PageSize> void Page<Obj, PageSize>::deallocate_all() { + fm_assert(!locked); + locked = true; for (auto i = 0u; i < PageSize; i++) if (used_map[i]) do_deallocate(storage[i]); @@ -86,12 +99,15 @@ void Page<Obj, PageSize>::deallocate_all() for (auto i = 0u; i < PageSize; i++) { auto& o = storage.data()[i]; - o.handle = {val++, 0}; + bool used = used_map[i]; + uint32_t new_ctr = used ? 1 : 0; + o.handle = {val++, o.handle.counter + new_ctr}; o.next = val; } first_free = start_index; used_count = 0; used_map = BitArray{ValueInit, PageSize}; + locked = false; } template<typename Obj, uint32_t PageSize> @@ -106,4 +122,10 @@ bool Page<Obj, PageSize>::is_full() return used_count == PageSize; } +template<typename Obj, uint32_t PageSize> +uint32_t Page<Obj, PageSize>::use_count() const +{ + return used_count; +} + } // namespace floormat::impl_handle |