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:
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);

View File

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

View File

@ -1,6 +1,5 @@
#pragma once
#include <limits>
#include <algorithm>
#include <utility>
#include <cstdlib>
@ -12,10 +11,6 @@ namespace mem {
class static_alloc {
public:
static constexpr std::size_t remain() {
return (std::numeric_limits<std::size_t>::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_);

View File

@ -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 <std::size_t Size>
static auto& fixed() {
static tls::pointer<fixed_pool<Size>> fp;
return *fp.create();
static synchronized<fixed_pool<Size>> pool;
return pool;
}
template <typename F>
@ -83,11 +81,11 @@ using allocator = allocator_wrapper<T, pool_alloc>;
template <typename Key, typename T>
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>
using vector = std::vector<T/*, allocator<T>*/>;
using vector = std::vector<T, allocator<T>>;
} // namespace mem
} // namespace ipc

View File

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