mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
remove locked_fixed_alloc
This commit is contained in:
parent
99926581d1
commit
fac45ec38f
@ -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
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user