Browse Source

fix objpool: add size tracking, improve allocation matching; fix msgbuf: clear pool on size change

fixes
Antonio SJ Musumeci 2 weeks ago
parent
commit
a9ea8374da
  1. 68
      vendored/libfuse/include/objpool.hpp
  2. 9
      vendored/libfuse/lib/fuse_msgbuf.cpp

68
vendored/libfuse/include/objpool.hpp

@ -30,13 +30,16 @@
struct DefaultAllocator struct DefaultAllocator
{ {
void* void*
allocate(size_t size_, size_t align_)
allocate(size_t size_,
size_t align_)
{ {
return ::operator new(size_, std::align_val_t{align_}); return ::operator new(size_, std::align_val_t{align_});
} }
void void
deallocate(void *ptr_, size_t /*size_*/, size_t align_)
deallocate(void *ptr_,
size_t /*size_*/,
size_t align_)
{ {
::operator delete(ptr_, std::align_val_t{align_}); ::operator delete(ptr_, std::align_val_t{align_});
} }
@ -60,11 +63,14 @@ private:
struct alignas(alignof(T)) Node struct alignas(alignof(T)) Node
{ {
Node *next; Node *next;
size_t alloc_size;
}; };
private: private:
static_assert(sizeof(T) >= sizeof(Node), "T must be at least pointer-sized");
static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible");
static_assert(sizeof(T) >= sizeof(Node),
"T must be at least pointer-sized + size_t");
static_assert(std::is_nothrow_destructible_v<T>,
"T must be nothrow destructible");
private: private:
static static
@ -116,30 +122,41 @@ public:
private: private:
Node* Node*
_pop_node()
_pop_node(const size_t required_size_)
{ {
mutex_lock(_mtx); mutex_lock(_mtx);
Node *node = _head;
if(node)
Node **prev = &_head;
while(*prev)
{ {
_head = node->next;
_pool_count.fetch_sub(1, std::memory_order_relaxed);
Node *node = *prev;
if(node->alloc_size >= required_size_)
{
*prev = node->next;
_pool_count.fetch_sub(1,std::memory_order_relaxed);
mutex_unlock(_mtx);
return node;
}
prev = &node->next;
} }
mutex_unlock(_mtx); mutex_unlock(_mtx);
return node;
return nullptr;;
} }
void void
_push_node(Node *node_)
_push_node(Node *node_,
const size_t alloc_size_)
{ {
node_->alloc_size = alloc_size_;
mutex_lock(_mtx); mutex_lock(_mtx);
node_->next = _head; node_->next = _head;
_head = node_; _head = node_;
_pool_count.fetch_add(1, std::memory_order_relaxed);
_pool_count.fetch_add(1,std::memory_order_relaxed);
mutex_unlock(_mtx); mutex_unlock(_mtx);
} }
@ -154,14 +171,14 @@ public:
head = _head; head = _head;
_head = nullptr; _head = nullptr;
_pool_count.store(0, std::memory_order_relaxed);
_pool_count.store(0,std::memory_order_relaxed);
mutex_unlock(_mtx); mutex_unlock(_mtx);
while(head) while(head)
{ {
Node *next = head->next; Node *next = head->next;
_allocator.deallocate(head, sizeof(Node), alignof(Node));
_allocator.deallocate(head,head->alloc_size,alignof(Node));
head = next; head = next;
} }
} }
@ -170,14 +187,16 @@ public:
T* T*
alloc(Args&&... args_) alloc(Args&&... args_)
{ {
return _alloc_impl(sizeof(T), std::forward<Args>(args_)...);
return _alloc_impl(sizeof(T),
std::forward<Args>(args_)...);
} }
template<typename... Args> template<typename... Args>
T* T*
alloc_size(size_t size_, Args&&... args_) alloc_size(size_t size_, Args&&... args_)
{ {
return _alloc_impl(size_, std::forward<Args>(args_)...);
return _alloc_impl(size_,
std::forward<Args>(args_)...);
} }
private: private:
@ -190,7 +209,7 @@ private:
assert(size_ >= sizeof(T)); assert(size_ >= sizeof(T));
node = _pop_node();
node = _pop_node(size_);
mem = (node ? mem = (node ?
static_cast<void*>(node) : static_cast<void*>(node) :
_allocator.allocate(size_, alignof(T))); _allocator.allocate(size_, alignof(T)));
@ -203,6 +222,8 @@ private:
{ {
if(!node) if(!node)
_allocator.deallocate(mem, size_, alignof(T)); _allocator.deallocate(mem, size_, alignof(T));
else
_push_node(node,node->alloc_size);
throw; throw;
} }
} }
@ -215,7 +236,8 @@ public:
} }
void void
free_size(T *obj_, size_t size_) noexcept
free_size(T *obj_,
size_t size_) noexcept
{ {
if(not obj_) if(not obj_)
return; return;
@ -225,9 +247,9 @@ public:
obj_->~T(); obj_->~T();
if(should_pool) if(should_pool)
_push_node(to_node(obj_));
_push_node(to_node(obj_),size_);
else else
_allocator.deallocate(obj_, size_, alignof(T));
_allocator.deallocate(obj_,size_,alignof(T));
} }
size_t size_t
@ -240,14 +262,14 @@ public:
gc() noexcept gc() noexcept
{ {
size_t count = _pool_count.load(std::memory_order_relaxed); size_t count = _pool_count.load(std::memory_order_relaxed);
size_t to_free = std::max(count / 10, size_t{1});
size_t to_free = std::max(count / 10,size_t{1});
for(size_t i = 0; i < to_free; ++i) for(size_t i = 0; i < to_free; ++i)
{ {
Node *node = _pop_node();
Node *node = _pop_node(0);
if(not node) if(not node)
break; break;
_allocator.deallocate(node, sizeof(Node), alignof(Node));
_allocator.deallocate(node,node->alloc_size,alignof(Node));
} }
} }
}; };

9
vendored/libfuse/lib/fuse_msgbuf.cpp

@ -148,7 +148,14 @@ msgbuf_get_pagesize()
void void
msgbuf_set_bufsize(const u64 size_in_pages_) msgbuf_set_bufsize(const u64 size_in_pages_)
{ {
g_bufsize = ((size_in_pages_ + MSGBUF_OVERHEAD_PAGES) * g_pagesize);
u64 new_bufsize;
new_bufsize = ((size_in_pages_ + MSGBUF_OVERHEAD_PAGES) * g_pagesize);
if(new_bufsize != g_bufsize)
{
g_bufsize = new_bufsize;
g_msgbuf_pool.clear();
}
} }
u64 u64

Loading…
Cancel
Save