3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-02-14 12:51:48 +00:00
yosys/kernel/threading.cc
Robert O'Callahan fb24763a15 Add work_pool_size, IntRange, item_range_for_worker, and ThreadIndex
We'll use these later in this PR.
2026-02-05 18:58:17 +00:00

95 lines
2.4 KiB
C++

#include "kernel/yosys_common.h"
#include "kernel/threading.h"
YOSYS_NAMESPACE_BEGIN
static int init_max_threads()
{
const char *v = getenv("YOSYS_MAX_THREADS");
if (v == nullptr)
return INT32_MAX;
return atoi(v);
}
static int get_max_threads()
{
static int max_threads = init_max_threads();
return max_threads;
}
static int init_work_units_per_thread_override()
{
const char *v = getenv("YOSYS_WORK_UNITS_PER_THREAD");
if (v == nullptr)
return 0;
return atoi(v);
}
static int get_work_units_per_thread_override()
{
static int work_units_per_thread = init_work_units_per_thread_override();
return work_units_per_thread;
}
void DeferredLogs::flush()
{
for (auto &m : logs)
if (m.error)
YOSYS_NAMESPACE_PREFIX log_error("%s", m.text.c_str());
else
YOSYS_NAMESPACE_PREFIX log("%s", m.text.c_str());
}
int ThreadPool::pool_size(int reserved_cores, int max_worker_threads)
{
#ifdef YOSYS_ENABLE_THREADS
int available_threads = std::min<int>(std::thread::hardware_concurrency(), get_max_threads());
int num_threads = std::min(available_threads - reserved_cores, max_worker_threads);
return std::max(0, num_threads);
#else
return 0;
#endif
}
int ThreadPool::work_pool_size(int reserved_cores, int work_units, int work_units_per_thread)
{
int work_units_per_thread_override = get_work_units_per_thread_override();
if (work_units_per_thread_override > 0)
work_units_per_thread = work_units_per_thread_override;
return pool_size(reserved_cores, work_units / work_units_per_thread);
}
ThreadPool::ThreadPool(int pool_size, std::function<void(int)> b)
: body(std::move(b))
{
#ifdef YOSYS_ENABLE_THREADS
threads.reserve(pool_size);
for (int i = 0; i < pool_size; i++)
threads.emplace_back([i, this]{ body(i); });
#else
log_assert(pool_size == 0);
#endif
}
ThreadPool::~ThreadPool()
{
#ifdef YOSYS_ENABLE_THREADS
for (auto &t : threads)
t.join();
#endif
}
IntRange item_range_for_worker(int num_items, int thread_num, int num_threads)
{
if (num_threads <= 1) {
return {0, num_items};
}
int items_per_thread = num_items / num_threads;
int extra_items = num_items % num_threads;
// The first `extra_items` threads get one extra item.
int start = thread_num * items_per_thread + std::min(thread_num, extra_items);
int end = (thread_num + 1) * items_per_thread + std::min(thread_num + 1, extra_items);
return {start, end};
}
YOSYS_NAMESPACE_END