Commit 66aaa36d authored by Dominik Charousset's avatar Dominik Charousset

Add `set_scheduler` function

The new function allows users to deploy a custom scheduler either by
implementing `abstract_coordinator` directly or by using the policy-based
implementation with different policies. Relates #140.
parent 808dc849
...@@ -61,6 +61,9 @@ class singletons { ...@@ -61,6 +61,9 @@ class singletons {
static scheduler::abstract_coordinator* get_scheduling_coordinator(); static scheduler::abstract_coordinator* get_scheduling_coordinator();
// returns false if singleton is already defined
static bool set_scheduling_coordinator(scheduler::abstract_coordinator*);
static group_manager* get_group_manager(); static group_manager* get_group_manager();
static actor_registry* get_actor_registry(); static actor_registry* get_actor_registry();
......
...@@ -46,6 +46,9 @@ namespace scheduler { ...@@ -46,6 +46,9 @@ namespace scheduler {
class abstract_coordinator; class abstract_coordinator;
/**
* @brief Base class for work-stealing workers.
*/
class abstract_worker : public execution_unit { class abstract_worker : public execution_unit {
friend class abstract_coordinator; friend class abstract_coordinator;
...@@ -70,6 +73,12 @@ class abstract_worker : public execution_unit { ...@@ -70,6 +73,12 @@ class abstract_worker : public execution_unit {
}; };
/**
* @brief A coordinator creates the workers, manages delayed sends and
* the central printer instance for {@link aout}. It also forwards
* sends from detached workers or non-actor threads to randomly
* chosen workers.
*/
class abstract_coordinator { class abstract_coordinator {
friend class detail::singletons; friend class detail::singletons;
...@@ -137,7 +146,7 @@ class abstract_coordinator { ...@@ -137,7 +146,7 @@ class abstract_coordinator {
}; };
/** /**
* @brief A work-stealing scheduling worker. * @brief Policy-based implementation of the abstract worker base class.
*/ */
template<class StealPolicy, class JobQueuePolicy> template<class StealPolicy, class JobQueuePolicy>
class worker : public abstract_worker { class worker : public abstract_worker {
...@@ -267,7 +276,7 @@ class worker : public abstract_worker { ...@@ -267,7 +276,7 @@ class worker : public abstract_worker {
}; };
/** /**
* @brief Central scheduling interface. * @brief Policy-based implementation of the abstract coordinator base class.
*/ */
template<class StealPolicy, class JobQueuePolicy> template<class StealPolicy, class JobQueuePolicy>
class coordinator : public abstract_coordinator { class coordinator : public abstract_coordinator {
...@@ -314,6 +323,26 @@ class coordinator : public abstract_coordinator { ...@@ -314,6 +323,26 @@ class coordinator : public abstract_coordinator {
} // namespace scheduler } // namespace scheduler
/**
* @brief Sets a user-defined scheduler.
* @note This function must be used before actor is spawned. Dynamically
* changing the scheduler at runtime is not supported.
* @throws std::logic_error if a scheduler is already defined
*/
void set_scheduler(scheduler::abstract_coordinator* ptr);
/**
* @brief Sets a user-defined scheduler using given policies. The scheduler
* is instantiated with @p nw number of workers.
* @note This function must be used before actor is spawned. Dynamically
* changing the scheduler at runtime is not supported.
* @throws std::logic_error if a scheduler is already defined
*/
template<class StealPolicy, class JobQueuePolicy>
void set_scheduler(size_t nw = std::thread::hardware_concurrency()) {
set_scheduler(new scheduler::coordinator<StealPolicy, JobQueuePolicy>(nw));
}
} // namespace cppa } // namespace cppa
#endif // CPPA_SCHEDULER_HPP #endif // CPPA_SCHEDULER_HPP
...@@ -297,4 +297,12 @@ void abstract_coordinator::enqueue(resumable* what) { ...@@ -297,4 +297,12 @@ void abstract_coordinator::enqueue(resumable* what) {
} }
} // namespace scheduler } // namespace scheduler
void set_scheduler(scheduler::abstract_coordinator* impl) {
if (!detail::singletons::set_scheduling_coordinator(impl)) {
delete impl;
throw std::logic_error("scheduler already defined");
}
}
} // namespace cppa } // namespace cppa
...@@ -88,6 +88,11 @@ scheduler::abstract_coordinator* singletons::get_scheduling_coordinator() { ...@@ -88,6 +88,11 @@ scheduler::abstract_coordinator* singletons::get_scheduling_coordinator() {
return lazy_get(s_scheduling_coordinator); return lazy_get(s_scheduling_coordinator);
} }
bool singletons::set_scheduling_coordinator(scheduler::abstract_coordinator*p) {
scheduler::abstract_coordinator* expected = nullptr;
return s_scheduling_coordinator.compare_exchange_weak(expected, p);
}
node_id singletons::get_node_id() { node_id singletons::get_node_id() {
return node_id{lazy_get(s_node_id)}; return node_id{lazy_get(s_node_id)};
} }
......
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