mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
use std::atomic<std::size_t> instead of flag for better performance in arm; cross-platform supporting; add more test cases
This commit is contained in:
parent
b3e2c80fc0
commit
c8e81e2794
@ -16,10 +16,10 @@ struct alignas(std::max_align_t) elem_array_head {
|
||||
using uc_t = std::uint16_t;
|
||||
using ac_t = std::atomic<uc_t>;
|
||||
|
||||
std::atomic<std::size_t> lc_ { 0 }; // write spin lock flag
|
||||
|
||||
ac_t cc_ { 0 }; // connection counter, using for broadcast
|
||||
ac_t wt_ { 0 }; // write index
|
||||
|
||||
std::atomic_flag lc_ ATOMIC_FLAG_INIT; // write spin lock flag
|
||||
};
|
||||
|
||||
enum : std::size_t {
|
||||
@ -93,7 +93,7 @@ public:
|
||||
}
|
||||
|
||||
void* acquire(void) {
|
||||
while (lc_.test_and_set(std::memory_order_acquire)) {
|
||||
while (lc_.exchange(1, std::memory_order_acquire)) {
|
||||
std::this_thread::yield();
|
||||
}
|
||||
elem_t* el = elem(wt_.load(std::memory_order_relaxed));
|
||||
@ -114,7 +114,7 @@ public:
|
||||
|
||||
void commit(void* /*ptr*/) {
|
||||
wt_.fetch_add(1, std::memory_order_relaxed);
|
||||
lc_.clear(std::memory_order_release);
|
||||
lc_.store(0, std::memory_order_release);
|
||||
}
|
||||
|
||||
uc_t cursor(void) const {
|
||||
|
||||
@ -84,8 +84,27 @@ public:
|
||||
return old;
|
||||
}
|
||||
|
||||
bool push(T const & item) {
|
||||
if (elems_ == nullptr) return false;
|
||||
auto ptr = elems_->acquire();
|
||||
::new (ptr) T(item);
|
||||
elems_->commit(ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
auto push(P&& param) // disable this if P is the same as T
|
||||
-> std::enable_if_t<!std::is_same<std::remove_reference_t<P>, T>::value, bool> {
|
||||
if (elems_ == nullptr) return false;
|
||||
auto ptr = elems_->acquire();
|
||||
::new (ptr) T { std::forward<P>(param) };
|
||||
elems_->commit(ptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename... P>
|
||||
bool push(P&&... params) {
|
||||
auto push(P&&... params) // some old compilers are not support this well
|
||||
-> std::enable_if_t<(sizeof...(P) != 1), bool> {
|
||||
if (elems_ == nullptr) return false;
|
||||
auto ptr = elems_->acquire();
|
||||
::new (ptr) T { std::forward<P>(params)... };
|
||||
|
||||
@ -293,41 +293,42 @@ void Unit::test_prod_cons_3v1(void) {
|
||||
test_prod_cons<3, 1>();
|
||||
}
|
||||
|
||||
template <int B, int E>
|
||||
struct test_cons_performance {
|
||||
template <int P, int C>
|
||||
struct test_performance {
|
||||
static void start(void) {
|
||||
test_prod_cons<1, B, false>();
|
||||
test_cons_performance<B + 1, E>::start();
|
||||
test_performance<P - 1, C - 1>::start();
|
||||
test_prod_cons<P, C, false>();
|
||||
}
|
||||
};
|
||||
|
||||
template <int E>
|
||||
struct test_cons_performance<E, E> {
|
||||
template <int C>
|
||||
struct test_performance<1, C> {
|
||||
static void start(void) {
|
||||
test_prod_cons<1, E, false>();
|
||||
test_performance<1, C - 1>::start();
|
||||
test_prod_cons<1, C, false>();
|
||||
}
|
||||
};
|
||||
|
||||
template <int B, int E>
|
||||
struct test_prod_performance {
|
||||
template <int P>
|
||||
struct test_performance<P, 1> {
|
||||
static void start(void) {
|
||||
test_prod_cons<B, 1, false>();
|
||||
test_prod_performance<B + 1, E>::start();
|
||||
test_performance<P - 1, 1>::start();
|
||||
test_prod_cons<P, 1, false>();
|
||||
}
|
||||
};
|
||||
|
||||
template <int E>
|
||||
struct test_prod_performance<E, E> {
|
||||
template <>
|
||||
struct test_performance<1, 1> {
|
||||
static void start(void) {
|
||||
test_prod_cons<E, 1, false>();
|
||||
test_prod_cons<1, 1, false>();
|
||||
}
|
||||
};
|
||||
|
||||
void Unit::test_prod_cons_performance(void) {
|
||||
test_cons_performance<1, 10>::start();
|
||||
test_prod_performance<1, 10>::start();
|
||||
test_prod_cons<3, 3, false>(); // just test
|
||||
test_prod_cons<5, 5>(); // test & verify
|
||||
test_performance<1 , 10>::start();
|
||||
test_performance<10, 1 >::start();
|
||||
test_performance<10, 10>::start();
|
||||
test_prod_cons <3 , 3 >(); // test & verify
|
||||
}
|
||||
|
||||
void Unit::test_queue(void) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user