use pool_alloc instead of std::allocator

This commit is contained in:
mutouyun 2018-12-29 22:42:26 +08:00
parent 8c75f8ad84
commit 2941007301
5 changed files with 68 additions and 53 deletions

View File

@ -80,6 +80,13 @@ class rw_lock {
}; };
public: 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 { void lock() noexcept {
for (unsigned k = 0;; ++k) { for (unsigned k = 0;; ++k) {
auto old = lc_.fetch_or(w_flag, std::memory_order_acquire); auto old = lc_.fetch_or(w_flag, std::memory_order_acquire);

View File

@ -60,8 +60,8 @@ template <typename T>
using remove_cv_ref_t = std::remove_cv_t<std::remove_reference_t<T>>; using remove_cv_ref_t = std::remove_cv_t<std::remove_reference_t<T>>;
template <typename Cache> template <typename Cache>
constexpr auto to_buff(Cache&& cac) -> Requires<std::is_same<remove_cv_ref_t<Cache>, buff_t>::value, buff_t> { constexpr auto to_buff(Cache&& cac) -> Requires<std::is_same<remove_cv_ref_t<Cache>, buff_t>::value, Cache&&> {
return cac; return std::forward<Cache>(cac);
} }
template <typename Cache> template <typename Cache>

View File

@ -1,6 +1,5 @@
#pragma once #pragma once
#include <limits>
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include <cstdlib> #include <cstdlib>
@ -12,10 +11,6 @@ namespace mem {
class static_alloc { class static_alloc {
public: public:
static constexpr std::size_t remain() {
return (std::numeric_limits<std::size_t>::max)();
}
static constexpr void clear() {} static constexpr void clear() {}
static constexpr void swap(static_alloc&) {} static constexpr void swap(static_alloc&) {}
@ -46,16 +41,6 @@ protected:
block_t* list_ = nullptr; block_t* list_ = nullptr;
public: 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*/) {}
void free(void* /*p*/, std::size_t) {} void free(void* /*p*/, std::size_t) {}
}; };
@ -127,16 +112,6 @@ protected:
} }
public: 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) { void free(void* p) {
if (p == nullptr) return; if (p == nullptr) return;
next(p) = cursor_; next(p) = cursor_;
@ -188,10 +163,6 @@ public:
std::swap(this->cursor_ , rhs.cursor_); std::swap(this->cursor_ , rhs.cursor_);
} }
std::size_t remain() const {
return detail::fixed_pool_base::remain() * block_size;
}
void clear() { void clear() {
alloc_.clear(); alloc_.clear();
init(init_expand_); init(init_expand_);

View File

@ -10,8 +10,6 @@
#include "memory/alloc.hpp" #include "memory/alloc.hpp"
#include "memory/wrapper.hpp" #include "memory/wrapper.hpp"
#include "tls_pointer.h"
namespace ipc { namespace ipc {
namespace mem { namespace mem {
@ -34,8 +32,8 @@ class pool_alloc {
private: private:
template <std::size_t Size> template <std::size_t Size>
static auto& fixed() { static auto& fixed() {
static tls::pointer<fixed_pool<Size>> fp; static synchronized<fixed_pool<Size>> pool;
return *fp.create(); return pool;
} }
template <typename F> template <typename F>
@ -83,11 +81,11 @@ using allocator = allocator_wrapper<T, pool_alloc>;
template <typename Key, typename T> template <typename Key, typename T>
using unordered_map = std::unordered_map< using unordered_map = std::unordered_map<
Key, T//, std::hash<Key>, std::equal_to<Key>, allocator<std::pair<const Key, T>> Key, T, std::hash<Key>, std::equal_to<Key>, allocator<std::pair<const Key, T>>
>; >;
template <typename T> template <typename T>
using vector = std::vector<T/*, allocator<T>*/>; using vector = std::vector<T, allocator<T>>;
} // namespace mem } // namespace mem
} // namespace ipc } // namespace ipc

View File

@ -4,8 +4,11 @@
#include <new> #include <new>
#include <mutex> #include <mutex>
#include <shared_mutex> #include <shared_mutex>
#include <vector> #include <tuple>
#include <map>
#include <functional>
#include <utility> #include <utility>
#include <cstddef>
#include "rw_lock.h" #include "rw_lock.h"
#include "tls_pointer.h" #include "tls_pointer.h"
@ -18,39 +21,75 @@ namespace mem {
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
template <typename AllocP> template <typename AllocP>
class synchronized_pool { class synchronized {
public: public:
using alloc_policy = AllocP; using alloc_policy = AllocP;
private: private:
rw_lock lc_; rw_lock lc_;
std::vector<alloc_policy*> allocs_; std::multimap<std::size_t, alloc_policy*, std::greater<std::size_t>> allocs_;
struct alloc_t { struct alloc_t {
synchronized_pool* t_; synchronized* t_;
alloc_policy* alc_; std::size_t s_ = 0;
alloc_policy* a_ = nullptr;
alloc_t(synchronized_pool* t) alloc_t(synchronized* t)
: t_ { 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() { ~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<alloc_t> alc;
return *alc.create(this);
}
public: public:
static constexpr std::size_t remain() { ~synchronized() {
return (std::numeric_limits<std::size_t>::max)(); for (auto& pair : allocs_) {
delete pair.second;
}
} }
static void* alloc() { void* alloc(std::size_t size) {
static tls::pointer<alloc_policy> alc; return alc_info().alloc(size);
return nullptr;
} }
static void* alloc(std::size_t) { void free(void* p) {
return alloc(); alc_info().free(p);
}
static void free(void* p, std::size_t /*size*/) {
free(p);
} }
}; };
@ -122,7 +161,7 @@ public:
return static_cast<pointer>(alloc_.alloc(count * sizeof(T))); return static_cast<pointer>(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)); alloc_.free(p, count * sizeof(T));
} }