source/Scheduler.cpp (26 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include <mariana-trench/Scheduler.h> namespace marianatrench { // We use the dependency graph as the source of truth since it is more precise // than the call graph (for instance, it takes into account // `no-join-virtual-overrides`). Scheduler::Scheduler(const Methods& methods, const Dependencies& dependencies) : strongly_connected_components_(methods, dependencies) {} void Scheduler::schedule( const ConcurrentSet<const Method*>& methods, std::function<void(const Method*, std::size_t)> enqueue, unsigned int threads) const { // Schedule components by their reverse topological order (leaves to roots) in // the set of strongly connected components. std::size_t current_thread = 0; for (const auto& component : strongly_connected_components_.components()) { bool next_thread = false; // Schedule all methods in this component on the same thread. // Iterating on the reverse order here seems to give callees before callers // more often, even though this is not guaranteed by Tarjan's algorithm. for (auto iterator = component.rbegin(), end = component.rend(); iterator != end; ++iterator) { const auto* method = *iterator; if (methods.count_unsafe(method) > 0) { next_thread = true; enqueue(method, current_thread); } } if (next_thread) { current_thread = (current_thread + 1) % threads; } } } } // namespace marianatrench