diff --git a/src/threading/Reaction.hpp b/src/threading/Reaction.hpp index acc8439f..6372d101 100644 --- a/src/threading/Reaction.hpp +++ b/src/threading/Reaction.hpp @@ -44,6 +44,9 @@ namespace threading { // Forward declare class ReactionTask; struct ReactionIdentifiers; + namespace scheduler { + class Scheduler; + } // namespace scheduler /** * This class holds the definition of a Reaction. @@ -131,6 +134,10 @@ namespace threading { /// The callback generator function (creates databound callbacks) TaskGenerator generator; + + /// Cached data for this reaction added by the scheduler + std::shared_ptr scheduler_data; + friend class scheduler::Scheduler; /// Let the scheduler mess with reaction objects }; } // namespace threading diff --git a/src/threading/scheduler/Scheduler.cpp b/src/threading/scheduler/Scheduler.cpp index 23ef8aa5..422001ce 100644 --- a/src/threading/scheduler/Scheduler.cpp +++ b/src/threading/scheduler/Scheduler.cpp @@ -188,8 +188,23 @@ namespace threading { return; } - // Get the pool and locks for the group group - auto pool = get_pool(task->pool_descriptor); + // If we have run this task before, we know which pool it should be submitted to and cached it + // This avoids every single submit having to lock a mutex to find the pool + std::shared_ptr pool; + if (task->parent) { + if (task->parent->scheduler_data) { + pool = std::static_pointer_cast(task->parent->scheduler_data); + } + else { + pool = get_pool(task->pool_descriptor); + task->parent->scheduler_data = pool; + } + } + else { + pool = get_pool(task->pool_descriptor); + } + + // Get any locks that are required for this task auto group_lock = get_groups_lock(task->id, task->priority, pool, task->group_descriptors); // If this task should run immediately and not limited by the group lock