Commit a61fb447 authored by neverlord's avatar neverlord

some performance tweaks

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