mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
add impl of force_push for single-single-unicast; make test_circ works
This commit is contained in:
parent
6850b47e3a
commit
d762634380
@ -45,8 +45,22 @@ struct prod_cons_impl<wr<relat::single, relat::single, trans::unicast>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename W, typename F, typename E>
|
template <typename W, typename F, typename E>
|
||||||
bool force_push(W* wrapper, F&& f, E* elems) {
|
bool force_push(W* /*wrapper*/, F&& f, E* elems) {
|
||||||
return push(wrapper, std::forward<F>(f), elems);
|
auto cur_wt = circ::index_of(wt_.load(std::memory_order_relaxed));
|
||||||
|
for (unsigned k = 0;;) {
|
||||||
|
auto cur_rd = rd_.load(std::memory_order_acquire);
|
||||||
|
if (cur_wt != circ::index_of(cur_rd - 1)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// full
|
||||||
|
if (rd_.compare_exchange_weak(cur_rd, cur_rd + 1, std::memory_order_acq_rel)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ipc::yield(k);
|
||||||
|
}
|
||||||
|
std::forward<F>(f)(&(elems[cur_wt].data_));
|
||||||
|
wt_.fetch_add(1, std::memory_order_release);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename W, typename F, typename E>
|
template <typename W, typename F, typename E>
|
||||||
@ -107,7 +121,7 @@ struct prod_cons_impl<wr<relat::multi , relat::multi, trans::unicast>>
|
|||||||
circ::index_of(rd_.load(std::memory_order_acquire))) {
|
circ::index_of(rd_.load(std::memory_order_acquire))) {
|
||||||
return false; // full
|
return false; // full
|
||||||
}
|
}
|
||||||
if (ct_.compare_exchange_weak(cur_ct, nxt_ct, std::memory_order_release)) {
|
if (ct_.compare_exchange_weak(cur_ct, nxt_ct, std::memory_order_acq_rel)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ipc::yield(k);
|
ipc::yield(k);
|
||||||
@ -118,7 +132,7 @@ struct prod_cons_impl<wr<relat::multi , relat::multi, trans::unicast>>
|
|||||||
el->f_ct_.store(~static_cast<flag_t>(cur_ct), std::memory_order_release);
|
el->f_ct_.store(~static_cast<flag_t>(cur_ct), std::memory_order_release);
|
||||||
while (1) {
|
while (1) {
|
||||||
auto cac_ct = el->f_ct_.load(std::memory_order_acquire);
|
auto cac_ct = el->f_ct_.load(std::memory_order_acquire);
|
||||||
if (cur_ct != wt_.load(std::memory_order_acquire)) {
|
if (cur_ct != wt_.load(std::memory_order_relaxed)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((~cac_ct) != cur_ct) {
|
if ((~cac_ct) != cur_ct) {
|
||||||
|
|||||||
@ -32,7 +32,6 @@ using cq_t = ea_t<
|
|||||||
sizeof(msg_t),
|
sizeof(msg_t),
|
||||||
pc_t<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
pc_t<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||||
>;
|
>;
|
||||||
cq_t* cq__;
|
|
||||||
|
|
||||||
bool operator==(msg_t const & m1, msg_t const & m2) {
|
bool operator==(msg_t const & m1, msg_t const & m2) {
|
||||||
return (m1.pid_ == m2.pid_) && (m1.dat_ == m2.dat_);
|
return (m1.pid_ == m2.pid_) && (m1.dat_ == m2.dat_);
|
||||||
@ -117,28 +116,28 @@ template <std::size_t D, typename P>
|
|||||||
struct test_cq<ea_t<D, P>> {
|
struct test_cq<ea_t<D, P>> {
|
||||||
using ca_t = ea_t<D, P>;
|
using ca_t = ea_t<D, P>;
|
||||||
using cn_t = decltype(std::declval<ca_t>().connect());
|
using cn_t = decltype(std::declval<ca_t>().connect());
|
||||||
|
using cr_t = decltype(std::declval<ca_t>().cursor());
|
||||||
|
|
||||||
typename quit_mode<P>::type quit_ = false;
|
typename quit_mode<P>::type quit_ = false;
|
||||||
ca_t* ca_;
|
ca_t* ca_;
|
||||||
cn_t cc_id_;
|
std::unordered_map<cn_t, cr_t> conns_;
|
||||||
|
|
||||||
test_cq(ca_t* ca) : ca_(ca) {}
|
test_cq(ca_t* ca) : ca_(ca) {}
|
||||||
|
|
||||||
cn_t connect() {
|
cn_t connect() {
|
||||||
return cc_id_ = ca_->connect();
|
auto it = conns_.emplace(ca_->connect(), ca_->cursor());
|
||||||
|
return it.first->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
ca_t* connect_send() {
|
||||||
|
return ca_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void disconnect(cn_t cc_id) {
|
void disconnect(cn_t cc_id) {
|
||||||
ca_->disconnect(cc_id);
|
ca_->disconnect(cc_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disconnect(ca_t* ca) {
|
void disconnect(ca_t*) {}
|
||||||
ca->disconnect(cc_id_);
|
|
||||||
}
|
|
||||||
|
|
||||||
cn_t connected_id() const noexcept {
|
|
||||||
return cc_id_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ca_t * elems() noexcept { return ca_; }
|
ca_t * elems() noexcept { return ca_; }
|
||||||
ca_t const * elems() const noexcept { return ca_; }
|
ca_t const * elems() const noexcept { return ca_; }
|
||||||
@ -150,10 +149,18 @@ struct test_cq<ea_t<D, P>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
void recv(cn_t cur, F&& proc) {
|
void recv(cn_t cn, F&& proc) {
|
||||||
|
|
||||||
|
struct que {
|
||||||
|
cn_t cn_;
|
||||||
|
// for ca_->pop
|
||||||
|
cn_t connected_id() const noexcept { return cn_; }
|
||||||
|
} q { cn };
|
||||||
|
|
||||||
|
cr_t& cur = conns_[cn];
|
||||||
while (1) {
|
while (1) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
while (ca_->pop(this, &cur, [&msg](void* p) {
|
while (ca_->pop(&q, &cur, [&msg](void* p) {
|
||||||
msg = *static_cast<msg_t*>(p);
|
msg = *static_cast<msg_t*>(p);
|
||||||
})) {
|
})) {
|
||||||
if (msg.pid_ < 0) {
|
if (msg.pid_ < 0) {
|
||||||
@ -167,10 +174,6 @@ struct test_cq<ea_t<D, P>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ca_t* connect_send() {
|
|
||||||
return ca_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void send(ca_t* ca, msg_t const & msg) {
|
void send(ca_t* ca, msg_t const & msg) {
|
||||||
while (!ca->push(this, [&msg](void* p) {
|
while (!ca->push(this, [&msg](void* p) {
|
||||||
(*static_cast<msg_t*>(p)) = msg;
|
(*static_cast<msg_t*>(p)) = msg;
|
||||||
@ -238,15 +241,13 @@ class Unit : public TestSuite {
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
void cleanupTestCase();
|
|
||||||
|
|
||||||
void test_inst();
|
void test_inst();
|
||||||
void test_prod_cons_1v1();
|
void test_prod_cons_1v1();
|
||||||
void test_prod_cons_1v3();
|
void test_prod_cons_1v3();
|
||||||
void test_prod_cons_performance();
|
void test_prod_cons_performance();
|
||||||
void test_queue();
|
void test_queue();
|
||||||
};
|
//};
|
||||||
// } unit__;
|
} unit__;
|
||||||
|
|
||||||
#include "test_circ.moc"
|
#include "test_circ.moc"
|
||||||
|
|
||||||
@ -255,11 +256,6 @@ constexpr int LoopCount = 1000000;
|
|||||||
|
|
||||||
void Unit::initTestCase() {
|
void Unit::initTestCase() {
|
||||||
TestSuite::initTestCase();
|
TestSuite::initTestCase();
|
||||||
cq__ = new cq_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unit::cleanupTestCase() {
|
|
||||||
delete cq__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::test_inst() {
|
void Unit::test_inst() {
|
||||||
@ -270,22 +266,10 @@ void Unit::test_inst() {
|
|||||||
|
|
||||||
QCOMPARE(static_cast<std::size_t>(cq_t::data_size), sizeof(msg_t));
|
QCOMPARE(static_cast<std::size_t>(cq_t::data_size), sizeof(msg_t));
|
||||||
|
|
||||||
std::cout << "sizeof(ea_t<sizeof(msg_t)>) = " << sizeof(*cq__) << std::endl;
|
std::cout << "sizeof(ea_t<sizeof(msg_t)>) = " << sizeof(cq_t) << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
template <int N, int M, bool V = true, int Loops = LoopCount>
|
|
||||||
void test_prod_cons() {
|
|
||||||
benchmark_prod_cons<N, M, Loops, std::conditional_t<V, cq_t, void>>(cq__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::test_prod_cons_1v1() {
|
void Unit::test_prod_cons_1v1() {
|
||||||
// ea_t<
|
|
||||||
// sizeof(msg_t),
|
|
||||||
// pc_t<ipc::relat::multi, ipc::relat::multi, ipc::trans::broadcast>
|
|
||||||
// > el_arr_mmb;
|
|
||||||
// benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_mmb);
|
|
||||||
// benchmark_prod_cons<2, 1, LoopCount, void>(&el_arr_mmb);
|
|
||||||
|
|
||||||
ea_t<
|
ea_t<
|
||||||
sizeof(msg_t),
|
sizeof(msg_t),
|
||||||
pc_t<ipc::relat::single, ipc::relat::single, ipc::trans::unicast>
|
pc_t<ipc::relat::single, ipc::relat::single, ipc::trans::unicast>
|
||||||
@ -307,8 +291,12 @@ void Unit::test_prod_cons_1v1() {
|
|||||||
benchmark_prod_cons<1, 1, LoopCount, decltype(el_arr_mmu)::policy_t>(&el_arr_mmu);
|
benchmark_prod_cons<1, 1, LoopCount, decltype(el_arr_mmu)::policy_t>(&el_arr_mmu);
|
||||||
benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_mmu);
|
benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_mmu);
|
||||||
|
|
||||||
test_prod_cons<1, 1>();
|
ea_t<
|
||||||
test_prod_cons<1, 1, false>();
|
sizeof(msg_t),
|
||||||
|
pc_t<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||||
|
> el_arr_smb;
|
||||||
|
benchmark_prod_cons<1, 1, LoopCount, cq_t>(&el_arr_smb);
|
||||||
|
benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_smb);
|
||||||
|
|
||||||
ea_t<
|
ea_t<
|
||||||
sizeof(msg_t),
|
sizeof(msg_t),
|
||||||
@ -316,6 +304,7 @@ void Unit::test_prod_cons_1v1() {
|
|||||||
> el_arr_mmb;
|
> el_arr_mmb;
|
||||||
benchmark_prod_cons<1, 1, LoopCount, cq_t>(&el_arr_mmb);
|
benchmark_prod_cons<1, 1, LoopCount, cq_t>(&el_arr_mmb);
|
||||||
benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_mmb);
|
benchmark_prod_cons<1, 1, LoopCount, void>(&el_arr_mmb);
|
||||||
|
benchmark_prod_cons<2, 1, LoopCount, void>(&el_arr_mmb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::test_prod_cons_1v3() {
|
void Unit::test_prod_cons_1v3() {
|
||||||
@ -333,8 +322,12 @@ void Unit::test_prod_cons_1v3() {
|
|||||||
benchmark_prod_cons<1, 3, LoopCount, decltype(el_arr_mmu)::policy_t>(&el_arr_mmu);
|
benchmark_prod_cons<1, 3, LoopCount, decltype(el_arr_mmu)::policy_t>(&el_arr_mmu);
|
||||||
benchmark_prod_cons<1, 3, LoopCount, void>(&el_arr_mmu);
|
benchmark_prod_cons<1, 3, LoopCount, void>(&el_arr_mmu);
|
||||||
|
|
||||||
test_prod_cons<1, 3>();
|
ea_t<
|
||||||
test_prod_cons<1, 3, false>();
|
sizeof(msg_t),
|
||||||
|
pc_t<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||||
|
> el_arr_smb;
|
||||||
|
benchmark_prod_cons<1, 3, LoopCount, cq_t>(&el_arr_smb);
|
||||||
|
benchmark_prod_cons<1, 3, LoopCount, void>(&el_arr_smb);
|
||||||
|
|
||||||
ea_t<
|
ea_t<
|
||||||
sizeof(msg_t),
|
sizeof(msg_t),
|
||||||
@ -353,10 +346,17 @@ void Unit::test_prod_cons_performance() {
|
|||||||
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount, void>(&el_arr_smu);
|
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount, void>(&el_arr_smu);
|
||||||
});
|
});
|
||||||
|
|
||||||
ipc::detail::static_for<8>([](auto index) {
|
ea_t<
|
||||||
test_prod_cons<1, decltype(index)::value + 1, false>();
|
sizeof(msg_t),
|
||||||
|
pc_t<ipc::relat::single, ipc::relat::multi, ipc::trans::broadcast>
|
||||||
|
> el_arr_smb;
|
||||||
|
ipc::detail::static_for<8>([&el_arr_smb](auto index) {
|
||||||
|
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount, void>(&el_arr_smb);
|
||||||
|
});
|
||||||
|
// test & verify
|
||||||
|
ipc::detail::static_for<8>([&el_arr_smb](auto index) {
|
||||||
|
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount, cq_t>(&el_arr_smb);
|
||||||
});
|
});
|
||||||
test_prod_cons<1, 8>(); // test & verify
|
|
||||||
|
|
||||||
ea_t<
|
ea_t<
|
||||||
sizeof(msg_t),
|
sizeof(msg_t),
|
||||||
@ -398,7 +398,7 @@ void Unit::test_queue() {
|
|||||||
msg_t msg {};
|
msg_t msg {};
|
||||||
QVERIFY(!queue.pop(msg));
|
QVERIFY(!queue.pop(msg));
|
||||||
QCOMPARE(msg, (msg_t {}));
|
QCOMPARE(msg, (msg_t {}));
|
||||||
QVERIFY(sizeof(decltype(queue)::elems_t) <= sizeof(*cq__));
|
QVERIFY(sizeof(decltype(queue)::elems_t) <= sizeof(cq_t));
|
||||||
|
|
||||||
ipc::detail::static_for<16>([](auto index) {
|
ipc::detail::static_for<16>([](auto index) {
|
||||||
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount>((queue_t*)nullptr);
|
benchmark_prod_cons<1, decltype(index)::value + 1, LoopCount>((queue_t*)nullptr);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user