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 {
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 actor_registry* get_actor_registry();
......
......@@ -46,6 +46,9 @@ namespace scheduler {
class abstract_coordinator;
/**
* @brief Base class for work-stealing workers.
*/
class abstract_worker : public execution_unit {
friend class abstract_coordinator;
......@@ -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 {
friend class detail::singletons;
......@@ -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>
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>
class coordinator : public abstract_coordinator {
......@@ -314,6 +323,26 @@ class coordinator : public abstract_coordinator {
} // 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
#endif // CPPA_SCHEDULER_HPP
......@@ -297,4 +297,12 @@ void abstract_coordinator::enqueue(resumable* what) {
}
} // 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
......@@ -88,6 +88,11 @@ scheduler::abstract_coordinator* singletons::get_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() {
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