21 const int TasksCnt = 100;
26 int IncrementsPerTask = 1000;
32 auto ScheduleIncrements = [&]() {
33 for (
int TaskI = 0; TaskI < TasksCnt; ++TaskI) {
34 Tasks.
runAsync(
"task", [&Counter, &Mutex, IncrementsPerTask]() {
35 for (
int Increment = 0; Increment < IncrementsPerTask; ++Increment) {
36 std::lock_guard<std::mutex> Lock(Mutex);
46 std::lock_guard<std::mutex> Lock(Mutex);
52 std::lock_guard<std::mutex> Lock(Mutex);
53 ASSERT_EQ(Counter, TasksCnt * IncrementsPerTask);
57 std::lock_guard<std::mutex> Lock(Mutex);
63 std::lock_guard<std::mutex> Lock(Mutex);
64 ASSERT_EQ(Counter, TasksCnt * IncrementsPerTask);
68 const unsigned NumThreads = 5;
69 const unsigned NumKeys = 100;
70 const unsigned NumIterations = 100;
73 std::atomic<unsigned> ComputeCount(0);
74 std::atomic<int> ComputeResult[NumKeys];
75 std::fill(std::begin(ComputeResult), std::end(ComputeResult), -1);
78 for (
unsigned I = 0; I < NumThreads; ++I)
79 Tasks.
runAsync(
"worker" + std::to_string(I), [&] {
80 for (unsigned J = 0; J < NumIterations; J++)
81 for (unsigned K = 0; K < NumKeys; K++) {
82 int Result = Cache.get(K, [&] { return ++ComputeCount; });
83 EXPECT_THAT(ComputeResult[K].exchange(Result),
84 testing::AnyOf(-1, Result))
85 <<
"Got inconsistent results from memoize";
89 EXPECT_GE(ComputeCount, NumKeys) <<
"Computed each key once";
90 EXPECT_LE(ComputeCount, NumThreads * NumKeys)
91 <<
"Worst case, computed each key in every thread";
92 for (
int Result : ComputeResult)
93 EXPECT_GT(Result, 0) <<
"All results in expected domain";