diff --git a/libfuse/include/objpool.hpp b/libfuse/include/objpool.hpp index 7aa2ecc6..e8630732 100644 --- a/libfuse/include/objpool.hpp +++ b/libfuse/include/objpool.hpp @@ -16,6 +16,8 @@ #pragma once +#include +#include #include #include #include @@ -45,6 +47,7 @@ private: private: std::mutex _mtx; Node *_head = nullptr; + std::atomic _pooled_count{0}; public: ObjPool() = default; @@ -66,7 +69,10 @@ private: Node *node = _head; if(node) - _head = node->next; + { + _head = node->next; + _pooled_count.fetch_sub(1, std::memory_order_relaxed); + } return node; } @@ -78,6 +84,7 @@ private: node_->next = _head; _head = node_; + _pooled_count.fetch_add(1, std::memory_order_relaxed); } public: @@ -90,6 +97,7 @@ public: std::lock_guard lock(_mtx); head = _head; _head = nullptr; + _pooled_count.store(0, std::memory_order_relaxed); } while(head) @@ -133,4 +141,25 @@ public: _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)}); + } + } }; diff --git a/libfuse/lib/fuse.cpp b/libfuse/lib/fuse.cpp index 7cc9d8e7..c7e4bf1f 100644 --- a/libfuse/lib/fuse.cpp +++ b/libfuse/lib/fuse.cpp @@ -3583,10 +3583,6 @@ metrics_log_nodes_info(FILE *file_) struct tm tm; struct timeval tv; 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); localtime_r(&tv.tv_sec,&tm); @@ -3594,15 +3590,6 @@ metrics_log_nodes_info(FILE *file_) 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), "time: %s\n" "sizeof(node): %" PRIu64 "\n" @@ -3612,10 +3599,6 @@ metrics_log_nodes_info(FILE *file_) "node name_table size: %" PRIu64 "\n" "node name_table usage: %" 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 allocation 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.use, (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_alloc_count(), msgbuf_avail_count(), @@ -3719,7 +3698,7 @@ void fuse_gc() { SysLog::info("running thorough garbage collection"); - node_gc(); + node_clear(); msgbuf_gc(); fuse_malloc_trim(); } @@ -3728,7 +3707,7 @@ void fuse_gc1() { SysLog::info("running basic garbage collection"); - node_gc1(); + node_gc(); msgbuf_gc_10percent(); fuse_malloc_trim(); } diff --git a/libfuse/lib/node.cpp b/libfuse/lib/node.cpp index fee37df1..0e52a104 100644 --- a/libfuse/lib/node.cpp +++ b/libfuse/lib/node.cpp @@ -1,60 +1,29 @@ #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 g_NODE_POOL; node_t* node_alloc() { - return (node_t*)lfmp_calloc(&g_NODE_FMP); + return g_NODE_POOL.alloc(); } void 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 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(); } diff --git a/libfuse/lib/node.hpp b/libfuse/lib/node.hpp index 73d7cb97..cd35ef2f 100644 --- a/libfuse/lib/node.hpp +++ b/libfuse/lib/node.hpp @@ -1,10 +1,10 @@ #pragma once #include "lock.h" -#include "lfmp.h" -typedef struct node_s node_t; -struct node_s +#include + +struct node_t { node_t *name_next; node_t *id_next; @@ -26,6 +26,5 @@ struct node_s node_t *node_alloc(); void node_free(node_t*); -int node_gc1(); void node_gc(); -lfmp_t *node_lfmp(); +void node_clear();