Commit a61fb447 authored by neverlord's avatar neverlord

some performance tweaks

parent 3d38389e
......@@ -75,7 +75,7 @@ class invokable : public invokable_base
public:
virtual intermediate* get_intermediate(const any_tuple&) const = 0;
virtual intermediate* get_intermediate(const any_tuple&) = 0;
};
......@@ -83,13 +83,31 @@ template<class TupleView, class MatchFunction, class TargetFun>
class invokable_impl : public invokable
{
struct iimpl : intermediate
{
const TargetFun& m_target;
TupleView m_args;
iimpl(const TargetFun& tf) : m_target(tf)
{
}
void invoke() // override
{
cppa::invoke(m_target, m_args);
}
};
MatchFunction m_match;
TargetFun m_target;
iimpl m_iimpl;
public:
invokable_impl(MatchFunction&& mm, const TargetFun& mt)
: m_match(std::move(mm)), m_target(mt)
: m_match(std::move(mm)), m_target(mt), m_iimpl(m_target)
{
}
......@@ -105,44 +123,45 @@ class invokable_impl : public invokable
return false;
}
intermediate* get_intermediate(const any_tuple& data) const
intermediate* get_intermediate(const any_tuple& data)
{
std::vector<size_t> mv;
if (m_match(data, &mv))
{
m_iimpl.m_args = TupleView(data.vals(), std::move(mv));
return &m_iimpl;
}
return nullptr;
}
};
template<template<class...> class TupleClass, class MatchFunction, class TargetFun>
class invokable_impl<TupleClass<>, MatchFunction, TargetFun> : public invokable
{
struct iimpl : intermediate
{
TupleView m_args;
const TargetFun& m_target;
iimpl(TupleView&& tv, const TargetFun& tf)
: m_args(std::move(tv)), m_target(tf)
iimpl(const TargetFun& tf) : m_target(tf)
{
}
void invoke() // override
void invoke()
{
cppa::invoke(m_target, m_args);
m_target();
}
};
std::vector<size_t> mv;
return (m_match(data, &mv)) ? new iimpl(TupleView(data.vals(),
std::move(mv)),
m_target)
: nullptr;
}
};
template<template<class...> class TupleClass, class MatchFunction, class TargetFun>
class invokable_impl<TupleClass<>, MatchFunction, TargetFun> : public invokable
{
MatchFunction m_match;
TargetFun m_target;
iimpl m_iimpl;
public:
invokable_impl(MatchFunction&& mm, const TargetFun& mt)
: m_match(std::move(mm)), m_target(mt)
: m_match(std::move(mm)), m_target(mt), m_iimpl(m_target)
{
}
......@@ -156,22 +175,9 @@ class invokable_impl<TupleClass<>, MatchFunction, TargetFun> : public invokable
return false;
}
intermediate* get_intermediate(const any_tuple& data) const
{
struct iimpl : intermediate
{
const TargetFun& m_target;
iimpl(const TargetFun& tf) : m_target(tf)
{
}
void invoke()
intermediate* get_intermediate(const any_tuple& data)
{
m_target();
}
};
return m_match(data, nullptr) ? new iimpl(m_target) : nullptr;
return m_match(data, nullptr) ? &m_iimpl : nullptr;
}
};
......
......@@ -41,6 +41,8 @@ class tuple_view
typedef cow_ptr<detail::abstract_tuple> vals_t;
tuple_view() : m_vals(tuple<ElementTypes...>().vals()) { }
static tuple_view from(const vals_t& vals)
{
return tuple_view(vals);
......@@ -61,6 +63,18 @@ class tuple_view
{
}
tuple_view& operator=(const tuple_view& other)
{
m_vals = other.m_vals;
return *this;
}
tuple_view& operator=(tuple_view&& other)
{
m_vals = std::move(other.m_vals);
return *this;
}
tuple_view(const tuple_view&) = default;
inline const vals_t& vals() const
......
CXX = /opt/local/bin/g++-mp-4.6
#CXX = /usr/bin/g++-4.6
#CXX = /opt/local/bin/g++-mp-4.6
CXX = /usr/bin/g++-4.6
CXXFLAGS = -std=c++0x -pedantic -Wall -Wextra -I/opt/local/include/ -I../ -fpermissive -O2
LIBS = -L../.libs/ -lcppa -L/opt/local/lib -L/usr/lib -lboost_thread-mt
......
......@@ -12,14 +12,14 @@ void counter_actor()
long count = 0;
receive_loop
(
on<atom("AddCount"), long>() >> [&](long val)
{
count += val;
},
on<atom("Get"), actor_ptr>() >> [&](actor_ptr client)
{
send(client, count);
count = 0;
},
on<atom("AddCount"), long>() >> [&](long val)
{
count += val;
}
);
}
......@@ -28,9 +28,11 @@ long the_test(int msg_count)
{
constexpr long val = 100;
auto counter = spawn(counter_actor);
auto msg = make_tuple(atom("AddCount"), val);
for (int i = 0; i < msg_count; ++i)
{
send(counter, atom("AddCount"), val);
counter->enqueue(msg);
//send(counter, atom("AddCount"), val);
}
send(counter, atom("Get"), self());
long result = 0;
......@@ -41,7 +43,7 @@ long the_test(int msg_count)
result = value;
}
);
send(counter, atom(":Exit"), exit_reason::user_defined);
send(counter, atom(":Exit"), self(), exit_reason::user_defined);
return result;
}
......@@ -62,4 +64,3 @@ int main()
await_all_others_done();
return 0;
}
......@@ -87,7 +87,7 @@ bool blocking_message_queue_impl::dq(std::unique_ptr<queue_node>& node,
{
return false;
}
std::unique_ptr<intermediate> imd(rules.get_intermediate(node->msg));
auto imd = rules.get_intermediate(node->msg);
if (imd)
{
m_last_dequeued = node->msg;
......@@ -101,7 +101,6 @@ bool blocking_message_queue_impl::dq(std::unique_ptr<queue_node>& node,
buffer.push_back(node.release());
return false;
}
}
bool blocking_message_queue_impl::dequeue_impl(timed_invoke_rules& rules,
......
......@@ -25,19 +25,20 @@ struct stack_node
stack_node* next;
void* s;
stack_node(): next(NULL) , s(/*mmap(0, STACK_SIZE,
stack_node(): next(NULL) , s(mmap(0, STACK_SIZE,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON,
-1,
0)*/ new char[STACK_SIZE])
0))
//new char[STACK_SIZE])
{
//memset(s, 0, STACK_SIZE);
}
~stack_node()
{
//munmap(s, STACK_SIZE);
delete[] reinterpret_cast<char*>(s);
munmap(s, STACK_SIZE);
//delete[] reinterpret_cast<char*>(s);
}
};
......
......@@ -88,7 +88,7 @@ struct thread_pool_scheduler::worker
}
if (m_done) return;
}
auto job = const_cast<scheduled_actor*>(m_job);
job = const_cast<scheduled_actor*>(m_job);
// run actor up to 300ms
reschedule = false;
tout = now();
......@@ -162,7 +162,6 @@ void thread_pool_scheduler::supervisor_loop(job_queue* jqueue,
}
}
while (!done);
cout << "supervisor_loop is done\n";
// quit
for (auto& w : workers)
{
......
......@@ -141,7 +141,7 @@ void yielding_message_queue_impl::yield_until_not_empty()
else
{
yield(yield_state::blocked);
CPPA_MEMORY_BARRIER();
//CPPA_MEMORY_BARRIER();
}
}
}
......@@ -176,7 +176,7 @@ yielding_message_queue_impl::dq(std::unique_ptr<queue_node>& node,
default: break;
}
std::unique_ptr<intermediate> imd(rules.get_intermediate(node->msg));
auto imd = rules.get_intermediate(node->msg);
if (imd)
{
m_last_dequeued = node->msg;
......
......@@ -189,7 +189,6 @@ size_t test__tuple()
auto intmd = inv.get_intermediate(t1);
CPPA_CHECK(intmd != nullptr);
if (intmd) intmd->invoke();
delete intmd;
CPPA_CHECK(!l1_invoked && l2_invoked && !l3_invoked);
reset_invoke_states();
......
......@@ -22,8 +22,6 @@ using namespace cppa;
using namespace cppa::util;
using namespace cppa::detail;
namespace { ucontext_t ctx[2]; }
struct pseudo_worker
{
......@@ -36,70 +34,38 @@ struct pseudo_worker
for (;;)
{
++m_count;
swapcontext(&ctx[1], &ctx[0]);
yield(m_count < 10 ? yield_state::ready : yield_state::done);
}
}
};
__thread pseudo_worker* t_worker = nullptr;
void coroutine()
void coroutine(void* worker)
{
(*t_worker)();
(*reinterpret_cast<pseudo_worker*>(worker))();
}
size_t test__yield_interface()
{
CPPA_TEST(test__yield_interface);
void* coroutine_stack = mmap(0,
SIGSTKSZ,
PROT_EXEC | PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON,
-1,
0);
pseudo_worker worker;
t_worker = &worker;
memset(&ctx[0], 0, sizeof(ucontext_t));
getcontext(&ctx[0]);
fiber fself;
fiber fcoroutine(coroutine, &worker);
memset(&ctx[1], 0, sizeof(ucontext_t));
getcontext(&ctx[1]);
ctx[1].uc_stack.ss_sp = coroutine_stack;
ctx[1].uc_stack.ss_size = SIGSTKSZ;
ctx[1].uc_link = &ctx[0];
makecontext(&ctx[1], coroutine, 0);
auto do_switch = []() { swapcontext(&ctx[0], &ctx[1]); };
//fiber fself;
//fiber fcoroutine(coroutine, nullptr);
/*
auto do_switch = [&]() { call(&fcoroutine, &fself); };
do_switch();
CPPA_CHECK(yielded_state() == yield_state::invalid);
do_switch();
CPPA_CHECK(yielded_state() == yield_state::ready);
do_switch();
CPPA_CHECK(yielded_state() == yield_state::blocked);
do_switch();
CPPA_CHECK(yielded_state() == yield_state::done);
do_switch();
CPPA_CHECK(yielded_state() == yield_state::killed);
*/
//for (int i = 1 ; i < 11; ++i)
while (worker.m_count < 11)
int i = 0;
do
{
do_switch();
++i;
}
while (yielded_state() != yield_state::done && i < 10);
CPPA_CHECK_EQUAL(worker.m_count, 10);
munmap(coroutine_stack, SIGSTKSZ);
CPPA_CHECK_EQUAL(yielded_state(), yield_state::done);
CPPA_CHECK_EQUAL(i, 10);
return CPPA_TEST_RESULT;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment