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

View File

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