Browse Source

Rework node obj pool to use objpool

pull/1620/head
Antonio SJ Musumeci 4 weeks ago
committed by trapexit
parent
commit
3f70e66ee3
  1. 31
      libfuse/include/objpool.hpp
  2. 25
      libfuse/lib/fuse.cpp
  3. 47
      libfuse/lib/node.cpp
  4. 9
      libfuse/lib/node.hpp

31
libfuse/include/objpool.hpp

@ -16,6 +16,8 @@
#pragma once #pragma once
#include <algorithm>
#include <atomic>
#include <mutex> #include <mutex>
#include <new> #include <new>
#include <utility> #include <utility>
@ -45,6 +47,7 @@ private:
private: private:
std::mutex _mtx; std::mutex _mtx;
Node *_head = nullptr; Node *_head = nullptr;
std::atomic<size_t> _pooled_count{0};
public: public:
ObjPool() = default; ObjPool() = default;
@ -66,7 +69,10 @@ private:
Node *node = _head; Node *node = _head;
if(node) if(node)
_head = node->next;
{
_head = node->next;
_pooled_count.fetch_sub(1, std::memory_order_relaxed);
}
return node; return node;
} }
@ -78,6 +84,7 @@ private:
node_->next = _head; node_->next = _head;
_head = node_; _head = node_;
_pooled_count.fetch_add(1, std::memory_order_relaxed);
} }
public: public:
@ -90,6 +97,7 @@ public:
std::lock_guard<std::mutex> lock(_mtx); std::lock_guard<std::mutex> lock(_mtx);
head = _head; head = _head;
_head = nullptr; _head = nullptr;
_pooled_count.store(0, std::memory_order_relaxed);
} }
while(head) while(head)
@ -133,4 +141,25 @@ public:
_push_node(to_node(obj_)); _push_node(to_node(obj_));
} }
size_t
size() const noexcept
{
return _pooled_count.load(std::memory_order_relaxed);
}
void
gc() noexcept
{
size_t count = _pooled_count.load(std::memory_order_relaxed);
size_t to_free = std::max(count / 10, size_t{1});
for(size_t i = 0; i < to_free; ++i)
{
Node *node = _pop_node();
if(not node)
break;
::operator delete(node, std::align_val_t{alignof(T)});
}
}
}; };

25
libfuse/lib/fuse.cpp

@ -3583,10 +3583,6 @@ metrics_log_nodes_info(FILE *file_)
struct tm tm; struct tm tm;
struct timeval tv; struct timeval tv;
uint64_t sizeof_node; uint64_t sizeof_node;
float node_usage_ratio;
uint64_t node_slab_count;
uint64_t node_avail_objs;
uint64_t node_total_alloc_mem;
gettimeofday(&tv,NULL); gettimeofday(&tv,NULL);
localtime_r(&tv.tv_sec,&tm); localtime_r(&tv.tv_sec,&tm);
@ -3594,15 +3590,6 @@ metrics_log_nodes_info(FILE *file_)
sizeof_node = sizeof(node_t); sizeof_node = sizeof(node_t);
lfmp_t *lfmp;
lfmp = node_lfmp();
lfmp_lock(lfmp);
node_slab_count = fmp_slab_count(&lfmp->fmp);
node_usage_ratio = fmp_slab_usage_ratio(&lfmp->fmp);
node_avail_objs = fmp_avail_objs(&lfmp->fmp);
node_total_alloc_mem = fmp_total_allocated_memory(&lfmp->fmp);
lfmp_unlock(lfmp);
snprintf(buf,sizeof(buf), snprintf(buf,sizeof(buf),
"time: %s\n" "time: %s\n"
"sizeof(node): %" PRIu64 "\n" "sizeof(node): %" PRIu64 "\n"
@ -3612,10 +3599,6 @@ metrics_log_nodes_info(FILE *file_)
"node name_table size: %" PRIu64 "\n" "node name_table size: %" PRIu64 "\n"
"node name_table usage: %" PRIu64 "\n" "node name_table usage: %" PRIu64 "\n"
"node name_table total allocated memory: %" PRIu64 "\n" "node name_table total allocated memory: %" PRIu64 "\n"
"node memory pool slab count: %" PRIu64 "\n"
"node memory pool usage ratio: %f\n"
"node memory pool avail objs: %" PRIu64 "\n"
"node memory pool total allocated memory: %" PRIu64 "\n"
"msgbuf bufsize: %" PRIu64 "\n" "msgbuf bufsize: %" PRIu64 "\n"
"msgbuf allocation count: %" PRIu64 "\n" "msgbuf allocation count: %" PRIu64 "\n"
"msgbuf available count: %" PRIu64 "\n" "msgbuf available count: %" PRIu64 "\n"
@ -3630,10 +3613,6 @@ metrics_log_nodes_info(FILE *file_)
(uint64_t)f.name_table.size, (uint64_t)f.name_table.size,
(uint64_t)f.name_table.use, (uint64_t)f.name_table.use,
(uint64_t)(f.name_table.size * sizeof(node_t*)), (uint64_t)(f.name_table.size * sizeof(node_t*)),
node_slab_count,
node_usage_ratio,
node_avail_objs,
node_total_alloc_mem,
msgbuf_get_bufsize(), msgbuf_get_bufsize(),
msgbuf_alloc_count(), msgbuf_alloc_count(),
msgbuf_avail_count(), msgbuf_avail_count(),
@ -3719,7 +3698,7 @@ void
fuse_gc() fuse_gc()
{ {
SysLog::info("running thorough garbage collection"); SysLog::info("running thorough garbage collection");
node_gc();
node_clear();
msgbuf_gc(); msgbuf_gc();
fuse_malloc_trim(); fuse_malloc_trim();
} }
@ -3728,7 +3707,7 @@ void
fuse_gc1() fuse_gc1()
{ {
SysLog::info("running basic garbage collection"); SysLog::info("running basic garbage collection");
node_gc1();
node_gc();
msgbuf_gc_10percent(); msgbuf_gc_10percent();
fuse_malloc_trim(); fuse_malloc_trim();
} }

47
libfuse/lib/node.cpp

@ -1,60 +1,29 @@
#include "node.hpp" #include "node.hpp"
#include "lfmp.h"
#include "objpool.hpp"
static lfmp_t g_NODE_FMP;
static
__attribute__((constructor))
void
node_constructor()
{
lfmp_init(&g_NODE_FMP,sizeof(node_t),256);
}
static
__attribute__((destructor))
void
node_destructor()
{
lfmp_destroy(&g_NODE_FMP);
}
static ObjPool<node_t> g_NODE_POOL;
node_t* node_t*
node_alloc() node_alloc()
{ {
return (node_t*)lfmp_calloc(&g_NODE_FMP);
return g_NODE_POOL.alloc();
} }
void void
node_free(node_t *node_) node_free(node_t *node_)
{ {
lfmp_free(&g_NODE_FMP,node_);
}
int
node_gc1()
{
return lfmp_gc(&g_NODE_FMP);
g_NODE_POOL.free(node_);
} }
void void
node_gc() node_gc()
{ {
int rv;
int fails;
fails = 0;
do
{
rv = node_gc1();
if(rv == 0)
fails++;
} while(rv || (fails < 3));
g_NODE_POOL.gc();
} }
lfmp_t*
node_lfmp()
void
node_clear()
{ {
return &g_NODE_FMP;
g_NODE_POOL.clear();
} }

9
libfuse/lib/node.hpp

@ -1,10 +1,10 @@
#pragma once #pragma once
#include "lock.h" #include "lock.h"
#include "lfmp.h"
typedef struct node_s node_t;
struct node_s
#include <cstdint>
struct node_t
{ {
node_t *name_next; node_t *name_next;
node_t *id_next; node_t *id_next;
@ -26,6 +26,5 @@ struct node_s
node_t *node_alloc(); node_t *node_alloc();
void node_free(node_t*); void node_free(node_t*);
int node_gc1();
void node_gc(); void node_gc();
lfmp_t *node_lfmp();
void node_clear();
Loading…
Cancel
Save