11#if TRACKTION_BENCHMARKS && GRAPH_BENCHMARKS_THREADS
12 #include "../../tracktion_core/utilities/tracktion_Benchmark.h"
15namespace tracktion {
inline namespace graph
18#if GRAPH_UNIT_TESTS_SEMAPHORE
24 :
juce::UnitTest (
"Semaphore",
"tracktion_graph") {}
27 void runTest()
override
29 runSemaphoreTests<Semaphore> (
"Semaphore");
30 runSemaphoreTests<LightweightSemaphore> (
"LightweightSemaphore");
34 template<
typename SemaphoreType>
37 beginTest (
juce::String (
"Semaphore basic tests").replace (
"Semaphore", semaphoreName));
40 SemaphoreType event (1);
41 expect (event.wait());
45 SemaphoreType event (2);
47 expect (event.timed_wait (100));
52 SemaphoreType event (2);
53 expect (event.wait());
54 expect (event.wait());
55 expect (! event.try_wait());
56 expect (! event.timed_wait (100));
60 beginTest (
juce::String (
"Semaphore wakeup tests").replace (
"Semaphore", semaphoreName));
62 constexpr int numThreads = 10;
70 for (
int i = 0; i < numThreads; ++i)
78 logMessage (
juce::String (std::chrono::duration_cast<std::chrono::microseconds> (signalDuration).
count()) +
"us");
87 if (numThreadsRunning == numThreads)
98 event.signal (numThreads);
101 for (
auto& t : threads)
104 expectEquals (counter.load(), numThreads);
109static SemaphoreTests semaphoreTests;
113#if TRACKTION_BENCHMARKS && GRAPH_BENCHMARKS_THREADS
121 :
juce::UnitTest (
"no_op",
"tracktion_benchmarks") {}
124 void runTest()
override
126 Benchmark benchmark (createBenchmarkDescription (
"Time",
"no_op",
"no_op"));
128 for (
int i = 0; i < 100'000; ++i)
134 BenchmarkList::getInstance().addResult (benchmark.getResult());
138static NoOpBenchmarks noOpBenchmarks;
145 ChronoNowBenchmarks()
146 :
juce::UnitTest (
"steady_clock::now",
"tracktion_benchmarks") {}
149 void runTest()
override
151 Benchmark benchmark (createBenchmarkDescription (
"Time",
"steady_clock::now",
"chrono::steady_clock::now"));
153 for (
int i = 0; i < 100'000; ++i)
160 BenchmarkList::getInstance().addResult (benchmark.getResult());
164static ChronoNowBenchmarks chronoNowBenchmarks;
172 :
juce::UnitTest (
"juce::Time::getMillisecondCounterHiRes()",
"tracktion_benchmarks") {}
175 void runTest()
override
177 Benchmark benchmark (createBenchmarkDescription (
"Time",
"juce ms timer hi-res",
"juce::Time::getMillisecondCounterHiRes()"));
179 for (
int i = 0; i < 100'000; ++i)
186 BenchmarkList::getInstance().addResult (benchmark.getResult());
190static JUCEMsCounterHiRes juceMsCounterHiRes;
197 ThreadSignallingBenchmarks()
198 :
juce::UnitTest (
"Thread signalling",
"tracktion_benchmarks") {}
201 void runTest()
override
203 runConditionVariableBenchmarks();
204 runSemaphoreBenchmarks<Semaphore> (
"Semaphore");
205 runSemaphoreBenchmarks<LightweightSemaphore> (
"LightweightSemaphore");
207 runNonWaitingConditionVariableBenchmarks();
208 runNonWaitingSemaphoreBenchmarks<Semaphore> (
"Semaphore");
209 runNonWaitingSemaphoreBenchmarks<LightweightSemaphore> (
"LightweightSemaphore");
213 template<
typename SemaphoreType>
214 void runSemaphoreBenchmarks (
juce::String semaphoreName)
216 constexpr int numThreads = 10;
217 Benchmark benchmark (createBenchmarkDescription (
"Threads",
218 juce::String (
"Semaphore signal").replace (
"Semaphore", semaphoreName).toStdString(),
229 for (
int i = 0; i < numThreads; ++i)
241 if (numThreadsRunning == numThreads)
258 event.signal (numThreads);
263 for (
auto& t : threads)
266 BenchmarkList::getInstance().addResult (benchmark.getResult());
269 void runConditionVariableBenchmarks()
271 constexpr int numThreads = 10;
272 Benchmark benchmark (createBenchmarkDescription (
"Threads",
283 for (
int i = 0; i < numThreads; ++i)
295 if (numThreadsRunning == numThreads)
314 for (
auto& t : threads)
317 BenchmarkList::getInstance().addResult (benchmark.getResult());
320 template<
typename SemaphoreType>
321 void runNonWaitingSemaphoreBenchmarks (
juce::String semaphoreName)
323 constexpr int numThreads = 10;
325 Benchmark benchmark (createBenchmarkDescription (
"Threads",
326 juce::String (
"Semaphore signal").replace (
"Semaphore", semaphoreName).toStdString(),
327 juce::String (
"Signal numThreads (may not be waiting)").replace (
"numThreads",
juce::String (numThreads)).toStdString()));
336 for (
int i = 0; i < numThreads; ++i)
342 while (! threadShouldExit)
352 if (numThreadsRunning == numThreads)
361 for (
int i = 0; i < 100'000; ++i)
364 event.signal (numThreads);
369 threadShouldExit =
true;
371 while (numThreadsRunning > 0)
372 event.signal (numThreads);
374 for (
auto& t : threads)
377 BenchmarkList::getInstance().addResult (benchmark.getResult());
380 void runNonWaitingConditionVariableBenchmarks()
382 constexpr int numThreads = 10;
384 Benchmark benchmark (createBenchmarkDescription (
"Threads",
386 juce::String (
"Signal numThreads (may not be waiting)").replace (
"numThreads",
juce::String (numThreads)).toStdString()));
395 for (
int i = 0; i < numThreads; ++i)
401 while (! threadShouldExit)
411 if (numThreadsRunning == numThreads)
420 for (
int i = 0; i < 100'000; ++i)
428 threadShouldExit =
true;
430 while (numThreadsRunning > 0)
433 for (
auto& t : threads)
436 BenchmarkList::getInstance().addResult (benchmark.getResult());
440static ThreadSignallingBenchmarks threadSignallingBenchmarks;
static double getMillisecondCounterHiRes() noexcept
bool wait(double timeOutMilliseconds=-1.0) const
T emplace_back(T... args)