mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
remove locked_fixed_alloc
This commit is contained in:
parent
99926581d1
commit
fac45ec38f
@ -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
|
||||
|
||||
@ -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,12 +156,12 @@ private:
|
||||
std::tie(s_, a_) = *it;
|
||||
t_->allocs_.erase(it);
|
||||
}
|
||||
}
|
||||
if (a_ == nullptr) {
|
||||
a_ = static_cast<alloc_policy*>(locked_pool_alloc::alloc(sizeof(alloc_policy)));
|
||||
::new (a_) alloc_policy;
|
||||
a_ = static_cast<alloc_policy*>(page_pool_alloc::alloc(sizeof(alloc_policy)));
|
||||
}
|
||||
}
|
||||
::new (a_) alloc_policy;
|
||||
}
|
||||
|
||||
~alloc_t() {
|
||||
IPC_UNUSED_ auto guard = ipc::detail::unique_lock(t_->lc_);
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user