summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-07-13 19:01:05 +0200
committerStanislaw Halik <sthalik@misaki.pl>2024-07-14 13:04:42 +0200
commit3e4a66786b4cd1b4c691d91f27cb6fdf920fe586 (patch)
tree52e188f09afb0d81d857df4bc2f335eb42230c6d
parent1250fc680050848d777bbb37aa294ad5cff20436 (diff)
w
-rw-r--r--src/handle-fwd.hpp7
-rw-r--r--src/handle-page.hpp9
-rw-r--r--src/handle-page.inl30
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