Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

optimized event-based actors using functions

this patch saves one message per function-based actor to increase
scalability and performance
  • Loading branch information...
commit e957731f2035b43a7c7931a4069585cbeb86b7ee 1 parent 54e383d
@Neverlord Neverlord authored
View
2  cppa/event_based_actor.hpp
@@ -83,7 +83,7 @@ class event_based_actor : public scheduled_actor {
protected:
- event_based_actor();
+ event_based_actor(actor_state st = actor_state::blocked);
// provoke compiler errors for usage of receive() and related functions
View
2  cppa/opencl/actor_facade.hpp
@@ -126,7 +126,7 @@ class actor_facade<Ret(Args...)> : public actor {
template<long... Is>
void enqueue_impl(const actor_ptr& sender, any_tuple msg, message_id id, util::int_list<Is...>) {
- auto opt = tuple_cast<Args...>(msg);
+ auto opt = tuple_cast<typename util::rm_ref<Args>::type...>(msg);
if (opt) {
response_handle handle{this, sender, id};
size_t number_of_values = 1;
View
35 src/event_based_actor.cpp
@@ -36,6 +36,8 @@
#include "cppa/logging.hpp"
#include "cppa/event_based_actor.hpp"
+using namespace std;
+
namespace cppa {
class default_scheduled_actor : public event_based_actor {
@@ -46,16 +48,28 @@ class default_scheduled_actor : public event_based_actor {
typedef std::function<void()> fun_type;
- default_scheduled_actor(fun_type&& fun) : m_fun(std::move(fun)) { }
-
- void init() {
- become (
- on(atom("RUN")) >> [=] {
- CPPA_LOGS_TRACE("init$lambda", "");
- unbecome();
- m_fun();
+ default_scheduled_actor(fun_type&& fun)
+ : super(actor_state::ready), m_fun(std::move(fun)), m_initialized(false) { }
+
+ void init() { }
+
+ resume_result resume(util::fiber* f, actor_ptr& next) {
+ if (!m_initialized) {
+ scoped_self_setter sss{this};
+ m_initialized = true;
+ m_fun();
+ if (m_bhvr_stack.empty()) {
+ if (exit_reason() == exit_reason::not_exited) quit(exit_reason::normal);
+ set_state(actor_state::done);
+ m_bhvr_stack.clear();
+ m_bhvr_stack.cleanup();
+ on_exit();
+ next.swap(m_chained_actor);
+ set_state(actor_state::done);
+ return resume_result::actor_done;
}
- );
+ }
+ return event_based_actor::resume(f, next);
}
scheduled_actor_type impl_type() {
@@ -65,6 +79,7 @@ class default_scheduled_actor : public event_based_actor {
private:
fun_type m_fun;
+ bool m_initialized;
};
@@ -72,7 +87,7 @@ intrusive_ptr<event_based_actor> event_based_actor::from(std::function<void()> f
return detail::memory::create<default_scheduled_actor>(std::move(fun));
}
-event_based_actor::event_based_actor() : super(actor_state::blocked, true) { }
+event_based_actor::event_based_actor(actor_state st) : super(st, true) { }
void event_based_actor::dequeue(behavior&) {
quit(exit_reason::unallowed_function_call);
View
14 src/thread_pool_scheduler.cpp
@@ -209,20 +209,10 @@ actor_ptr thread_pool_scheduler::exec(spawn_options os, scheduled_actor_ptr p) {
return std::move(p);
}
p->attach_to_scheduler(this, is_hidden);
- if (p->has_behavior()) {
+ if (p->has_behavior() || p->impl_type() == default_event_based_impl) {
if (!is_hidden) get_actor_registry()->inc_running();
p->ref(); // implicit reference that's released if actor dies
- switch (p->impl_type()) {
- case default_event_based_impl: {
- p->enqueue(nullptr, make_any_tuple(atom("RUN")));
- break;
- }
- case context_switching_impl: {
- m_queue.push_back(p.get());
- break;
- }
- default: break; // nothing to do
- }
+ if (p->impl_type() != event_based_impl) m_queue.push_back(p.get());
}
else p->on_exit();
return std::move(p);
Please sign in to comment.
Something went wrong with that request. Please try again.