remove locked_fixed_alloc

This commit is contained in:
mutouyun 2019-01-25 13:08:33 +08:00
parent 99926581d1
commit fac45ec38f
2 changed files with 27 additions and 86 deletions

View File

@ -106,41 +106,14 @@ public:
namespace detail {
template <typename T>
class non_atomic {
T val_;
public:
void store(T val, std::memory_order) noexcept {
val_ = val;
}
T load(std::memory_order) const noexcept {
return val_;
}
bool compare_exchange_weak(T&, T val, std::memory_order) noexcept {
// always return true
val_ = val;
return true;
}
};
class non_lock {
public:
void lock (void) noexcept {}
void unlock(void) noexcept {}
};
template <template <typename> class Atomic>
class fixed_alloc_base {
protected:
std::size_t init_expand_;
Atomic<void*> cursor_;
void * cursor_;
void init(std::size_t init_expand) {
init_expand_ = init_expand;
cursor_.store(nullptr, std::memory_order_relaxed);
cursor_ = nullptr;
}
static void** node_p(void* node) {
@ -154,20 +127,13 @@ protected:
public:
void swap(fixed_alloc_base& rhs) {
std::swap(this->init_expand_, rhs.init_expand_);
auto tmp = this->cursor_.load(std::memory_order_relaxed);
this->cursor_.store(rhs.cursor_.load(std::memory_order_relaxed), std::memory_order_relaxed);
rhs.cursor_.store(tmp, std::memory_order_relaxed);
std::swap(this->cursor_ , rhs.cursor_ );
}
void free(void* p) {
if (p == nullptr) return;
while (1) {
next(p) = cursor_.load(std::memory_order_acquire);
if (cursor_.compare_exchange_weak(next(p), p, std::memory_order_release)) {
break;
}
std::this_thread::yield();
}
next(p) = cursor_;
cursor_ = p;
}
void free(void* p, std::size_t) {
@ -177,12 +143,10 @@ public:
} // namespace detail
template <std::size_t BlockSize, typename AllocP = scope_alloc<>,
template <typename> class Atomic = detail::non_atomic,
typename Lock = detail::non_lock>
class fixed_alloc : public detail::fixed_alloc_base<Atomic> {
template <std::size_t BlockSize, typename AllocP = scope_alloc<>>
class fixed_alloc : public detail::fixed_alloc_base {
public:
using base_t = detail::fixed_alloc_base<Atomic>;
using base_t = detail::fixed_alloc_base;
using alloc_policy = AllocP;
enum : std::size_t {
@ -195,22 +159,17 @@ public:
private:
alloc_policy alloc_;
Lock lc_;
void* expand() {
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lc_);
auto c = this->cursor_.load(std::memory_order_relaxed);
if (c != nullptr) {
return c;
void* try_expand() {
if (this->cursor_ != nullptr) {
return this->cursor_;
}
auto a = alloc_.alloc(block_size);
this->cursor_.store(a, std::memory_order_relaxed);
auto p = this->node_p(a);
auto p = this->node_p(this->cursor_ = alloc_.alloc(block_size));
auto size = alloc_.size_of(p);
if (size > 0) for (std::size_t i = 0; i < (size / block_size) - 1; ++i)
p = this->node_p((*p) = reinterpret_cast<byte_t*>(p) + block_size);
(*p) = nullptr;
return a;
return this->cursor_;
}
public:
@ -223,13 +182,11 @@ public:
public:
void swap(fixed_alloc& rhs) {
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lc_);
std::swap(this->alloc_, rhs.alloc_);
base_t::swap(rhs);
}
void clear() {
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lc_);
alloc_.clear();
this->init(this->init_expand_);
}
@ -239,14 +196,8 @@ public:
}
void* alloc() {
void* p;
while (1) {
p = expand();
if (this->cursor_.compare_exchange_weak(p, this->next(p), std::memory_order_release)) {
break;
}
std::this_thread::yield();
}
void* p = try_expand();
this->cursor_ = this->next(p);
return p;
}
@ -264,8 +215,5 @@ using page_alloc = fixed_alloc<4096>;
template <std::size_t BlockSize>
using page_fixed_alloc = fixed_alloc<BlockSize, page_alloc>;
template <std::size_t BlockSize>
using locked_fixed_alloc = fixed_alloc<BlockSize, page_alloc, std::atomic, ipc::spin_lock>;
} // namespace mem
} // namespace ipc

View File

@ -125,12 +125,12 @@ constexpr bool operator!=(const allocator_wrapper<T, AllocP>&, const allocator_w
////////////////////////////////////////////////////////////////
template <std::size_t BlockSize>
using locked_fixed = ipc::mem::detail::fixed<BlockSize, locked_fixed_alloc>;
using page_fixed = ipc::mem::detail::fixed<BlockSize, page_fixed_alloc>;
using locked_pool_alloc = detail::pool_alloc<locked_fixed>;
using page_pool_alloc = detail::pool_alloc<page_fixed>;
template <typename T>
using locked_allocator = allocator_wrapper<T, locked_pool_alloc>;
using page_allocator = allocator_wrapper<T, page_pool_alloc>;
template <typename AllocP>
class synchronized {
@ -140,7 +140,7 @@ public:
private:
spin_lock lc_;
std::multimap<std::size_t, alloc_policy*, std::less<std::size_t>,
locked_allocator<std::pair<const std::size_t, alloc_policy*>>> allocs_;
page_allocator<std::pair<const std::size_t, alloc_policy*>>> allocs_;
struct alloc_t {
synchronized* t_;
@ -156,11 +156,11 @@ private:
std::tie(s_, a_) = *it;
t_->allocs_.erase(it);
}
if (a_ == nullptr) {
a_ = static_cast<alloc_policy*>(page_pool_alloc::alloc(sizeof(alloc_policy)));
}
}
if (a_ == nullptr) {
a_ = static_cast<alloc_policy*>(locked_pool_alloc::alloc(sizeof(alloc_policy)));
::new (a_) alloc_policy;
}
::new (a_) alloc_policy;
}
~alloc_t() {
@ -189,22 +189,15 @@ private:
public:
~synchronized() {
for (auto& pair : allocs_) {
pair.second->~AllocP();
locked_pool_alloc::free(pair.second, sizeof(alloc_policy));
}
clear();
}
void clear() {
auto guard = ipc::detail::unique_lock(lc_);
std::vector<alloc_policy*> vec(allocs_.size());
std::size_t i = 0;
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(lc_);
for (auto& pair : allocs_) {
vec[i++] = pair.second;
pair.second->~AllocP();
page_pool_alloc::free(pair.second, sizeof(alloc_policy));
}
allocs_.clear();
guard.unlock();
for (auto alc : vec) delete alc;
}
void* alloc(std::size_t size) {