From 29410073010f61560735395593a22524385808ff Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sat, 29 Dec 2018 22:42:26 +0800 Subject: [PATCH] use pool_alloc instead of std::allocator --- include/rw_lock.h | 7 ++++ src/ipc.cpp | 4 +-- src/memory/alloc.hpp | 29 ----------------- src/memory/resource.hpp | 10 +++--- src/memory/wrapper.hpp | 71 +++++++++++++++++++++++++++++++---------- 5 files changed, 68 insertions(+), 53 deletions(-) diff --git a/include/rw_lock.h b/include/rw_lock.h index 7226c5c..49f1f6d 100644 --- a/include/rw_lock.h +++ b/include/rw_lock.h @@ -80,6 +80,13 @@ class rw_lock { }; public: + rw_lock() = default; + + rw_lock(const rw_lock&) = delete; + rw_lock& operator=(const rw_lock&) = delete; + rw_lock(rw_lock&&) = delete; + rw_lock& operator=(rw_lock&&) = delete; + void lock() noexcept { for (unsigned k = 0;; ++k) { auto old = lc_.fetch_or(w_flag, std::memory_order_acquire); diff --git a/src/ipc.cpp b/src/ipc.cpp index 64188b2..4536569 100644 --- a/src/ipc.cpp +++ b/src/ipc.cpp @@ -60,8 +60,8 @@ template using remove_cv_ref_t = std::remove_cv_t>; template -constexpr auto to_buff(Cache&& cac) -> Requires, buff_t>::value, buff_t> { - return cac; +constexpr auto to_buff(Cache&& cac) -> Requires, buff_t>::value, Cache&&> { + return std::forward(cac); } template diff --git a/src/memory/alloc.hpp b/src/memory/alloc.hpp index 9b125ce..b869a68 100644 --- a/src/memory/alloc.hpp +++ b/src/memory/alloc.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include #include @@ -12,10 +11,6 @@ namespace mem { class static_alloc { public: - static constexpr std::size_t remain() { - return (std::numeric_limits::max)(); - } - static constexpr void clear() {} static constexpr void swap(static_alloc&) {} @@ -46,16 +41,6 @@ protected: block_t* list_ = nullptr; public: - std::size_t remain() const { - std::size_t c = 0; - auto curr = list_; - while (curr != nullptr) { - ++c; - curr = curr->next_; - } - return c; - } - void free(void* /*p*/) {} void free(void* /*p*/, std::size_t) {} }; @@ -127,16 +112,6 @@ protected: } public: - std::size_t remain() const { - std::size_t c = 0; - void* curr = cursor_; - while (curr != nullptr) { - ++c; - curr = next(curr); - } - return c; - } - void free(void* p) { if (p == nullptr) return; next(p) = cursor_; @@ -188,10 +163,6 @@ public: std::swap(this->cursor_ , rhs.cursor_); } - std::size_t remain() const { - return detail::fixed_pool_base::remain() * block_size; - } - void clear() { alloc_.clear(); init(init_expand_); diff --git a/src/memory/resource.hpp b/src/memory/resource.hpp index fa87f93..152bcb9 100644 --- a/src/memory/resource.hpp +++ b/src/memory/resource.hpp @@ -10,8 +10,6 @@ #include "memory/alloc.hpp" #include "memory/wrapper.hpp" -#include "tls_pointer.h" - namespace ipc { namespace mem { @@ -34,8 +32,8 @@ class pool_alloc { private: template static auto& fixed() { - static tls::pointer> fp; - return *fp.create(); + static synchronized> pool; + return pool; } template @@ -83,11 +81,11 @@ using allocator = allocator_wrapper; template using unordered_map = std::unordered_map< - Key, T//, std::hash, std::equal_to, allocator> + Key, T, std::hash, std::equal_to, allocator> >; template -using vector = std::vector*/>; +using vector = std::vector>; } // namespace mem } // namespace ipc diff --git a/src/memory/wrapper.hpp b/src/memory/wrapper.hpp index 69fb531..55eab36 100644 --- a/src/memory/wrapper.hpp +++ b/src/memory/wrapper.hpp @@ -4,8 +4,11 @@ #include #include #include -#include +#include +#include +#include #include +#include #include "rw_lock.h" #include "tls_pointer.h" @@ -18,39 +21,75 @@ namespace mem { //////////////////////////////////////////////////////////////// template -class synchronized_pool { +class synchronized { public: using alloc_policy = AllocP; private: rw_lock lc_; - std::vector allocs_; + std::multimap> allocs_; struct alloc_t { - synchronized_pool* t_; - alloc_policy* alc_; + synchronized* t_; + std::size_t s_ = 0; + alloc_policy* a_ = nullptr; - alloc_t(synchronized_pool* t) - : t_ { t } - {} + alloc_t(synchronized* t) + : t_ { t } { + { + [[maybe_unused]] auto guard = std::unique_lock { t_->lc_ }; + auto it = t_->allocs_.begin(); + if (it != t_->allocs_.end()) { + std::tie(s_, a_) = *it; + t_->allocs_.erase(it); + } + } + if (a_ == nullptr) { + a_ = new alloc_policy; + } + } ~alloc_t() { + [[maybe_unused]] auto guard = std::unique_lock { t_->lc_ }; + t_->allocs_.emplace(s_, a_); + } + void* alloc(std::size_t size) { + void* p = a_->alloc(size); + if ((p != nullptr) && (s_ > 0)) { + --s_; + } + return p; + } + + void free(void* p) { + a_->free(p); + ++s_; } }; + auto& alc_info() { + static tls::pointer alc; + return *alc.create(this); + } + public: - static constexpr std::size_t remain() { - return (std::numeric_limits::max)(); + ~synchronized() { + for (auto& pair : allocs_) { + delete pair.second; + } } - static void* alloc() { - static tls::pointer alc; - return nullptr; + void* alloc(std::size_t size) { + return alc_info().alloc(size); } - static void* alloc(std::size_t) { - return alloc(); + void free(void* p) { + alc_info().free(p); + } + + static void free(void* p, std::size_t /*size*/) { + free(p); } }; @@ -122,7 +161,7 @@ public: return static_cast(alloc_.alloc(count * sizeof(T))); } - void deallocate(pointer p, size_type count) { + void deallocate(pointer p, size_type count) noexcept { alloc_.free(p, count * sizeof(T)); }