#pragma once #include #include #include #include "Common/Thread/ThreadManager.h" // Same as the latch from C++21, just counting upwards for no particular reason. struct WaitableCounter : public Waitable { public: WaitableCounter(int count) : count_(count) {} void Count() { std::unique_lock lock(mutex_); if (count_ == 0) { return; } count_--; if (count_ == 0) { // We were the last one to increment cond_.notify_all(); } } void Wait() override { std::unique_lock lock(mutex_); if (count_ == 0) { return; } cond_.wait(lock); } int count_; std::mutex mutex_; std::condition_variable cond_; }; // Note that upper bounds are non-inclusive: range is [lower, upper) WaitableCounter *ParallelRangeLoopWaitable(ThreadManager *threadMan, const std::function &loop, int lower, int upper, int minSize); // Note that upper bounds are non-inclusive: range is [lower, upper) void ParallelRangeLoop(ThreadManager *threadMan, const std::function &loop, int lower, int upper, int minSize); // Common utilities for large (!) memory copies. // Will only fall back to threads if it seems to make sense. void ParallelMemcpy(ThreadManager *threadMan, void *dst, const void *src, size_t bytes); void ParallelMemset(ThreadManager *threadMan, void *dst, uint8_t value, size_t bytes);