-
Notifications
You must be signed in to change notification settings - Fork 334
/
Copy pathbig_test.cpp
78 lines (71 loc) · 2.26 KB
/
big_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
//===--- big_test.cc -- Testing big (17+ byte) objects ------------ C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file tests atomic operations on big objects with aligned memory
// addresses.
//
// The types tested are: bigs.
// The ops tested are: cmpxchg.
// TODO: Test load/store, xchg.
//
// Please read the README before contributing.
//
//===----------------------------------------------------------------------===//
#include <iostream>
#include <thread>
#include <vector>
#include "util.h"
// V >> 56 = 66, so to prevent 32-bit overflow, kExpected must be less than
// 2^31 / 66 = 32 x 10^6.
#ifdef SMALL_PROBLEM_SIZE
static constexpr int kIterations = 1'000'000;
#else
static constexpr int kIterations = 3'000'000;
#endif
static constexpr int kExpected = kThreads * kIterations;
static constexpr int kBigSize = 10;
struct big_t {
int v[kBigSize];
};
// The big struct cmpxchg test is identical to the numeric cmpxchg test, except
// each element of the underlying array is incremented.
void looper_big_cmpxchg(big_t *abig, int success_model, int fail_model) {
for (int n = 0; n < kIterations; ++n) {
big_t desired, expected = {};
do {
desired = expected;
for (int k = 0; k < kBigSize; ++k)
desired.v[k]++;
} while (!__atomic_compare_exchange(abig, &expected, &desired, true,
success_model, fail_model));
}
}
void test_big_cmpxchg() {
std::vector<std::thread> pool;
for (int success_model : atomic_compare_exchange_models) {
for (int fail_model : atomic_compare_exchange_models) {
big_t abig = {};
for (int n = 0; n < kThreads; ++n)
pool.emplace_back(looper_big_cmpxchg, &abig, success_model, fail_model);
for (int n = 0; n < kThreads; ++n)
pool[n].join();
pool.clear();
for (int n = 0; n < kBigSize; ++n)
if (abig.v[n] != kExpected)
fail();
}
}
}
void test_big() {
std::cout << "Testing big\n";
test_big_cmpxchg();
}
int main() {
test_big();
std::cout << "PASSED\n";
}