Skip to content

Commit 46300e0

Browse files
committed
Add float128. Remove nonatomic tests, add README.
1 parent 6b280a8 commit 46300e0

9 files changed

+144
-391
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
Atomic runtime library tests
2+
3+
========
4+
5+
These tests aim to capture real-world multithreaded use cases of atomic
6+
builtins. Each test focuses on a single atomic operation. Those using multiple
7+
operations can be compared with other tests using the same operations to isolate
8+
bugs to a single atomic operation.
9+
10+
Each test consists of a "looper" body and a test script. The test script
11+
instantiates 10 threads, each running the looper. The loopers contend the same
12+
memory address, performing atomic operations on it. Each looper executes
13+
10^6 times for a total of 10^7 operations. The resultant value in the contended
14+
pointer is compared against a closed-form solution. It's expected that the two
15+
values equate.
16+
17+
For example, a looper that increments the shared pointer is expected to end up
18+
with a value of 10^7. If its final value is not that, the test fails.
19+
20+
Each test is performed on all relevant types.
21+
22+
========
23+
24+
Future test writers should be aware that the set of all tests that appear to
25+
test atomicity is not the set of all tests that test atomicity. In fact, tests
26+
that may test atomicity on one processor may not test atomicity on a different
27+
processor.
28+
29+
As such, test writers are encouraged to write nonatomic variants of their tests,
30+
and verify that they pass in a variety of scenarios.

SingleSource/UnitTests/Atomic/big_test.cpp

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,14 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// The following text is present in each test file:
10-
//
11-
// These tests aim to capture real-world multithreaded use cases of atomic
12-
// builtins. Each test focuses on a single atomic operation. Those using
13-
// multiple operations can be compared with other tests using the same
14-
// operations to isolate bugs to a single atomic operation.
15-
//
16-
// Each test consists of a "looper" body and a test script. The test script
17-
// instantiates 10 threads, each running the looper. The loopers contend the
18-
// same memory address, performing atomic operations on it. Each looper executes
19-
// 10^6 times for a total of 10^7 operations. The resultant value in the
20-
// contended pointer is compared against a closed-form solution. It's expected
21-
// that the two values equate.
22-
//
23-
// For example, a looper that increments the shared pointer is expected to end
24-
// up with a value of 10^7. If its final value is not that, the test fails.
25-
//
26-
// Each test also tests the corresponding nonatomic operation with a separate
27-
// shared variable. Ideally, this value differs from the atomic "correct" value,
28-
// and the test can compare the two. In reality, some simpler operations (e.g.
29-
// those conducted through the ALU) can still end up with the correct answer,
30-
// even when performed nonatomically. These tests do not check the nonatomic
31-
// result, although it is still outputted to aid in debugging.
32-
//
33-
// Each test is performed on all relevant types.
34-
//
35-
//===----------------------------------------------------------------------===//
36-
//
379
// This file tests atomic operations on big objects with aligned memory
3810
// addresses.
3911
//
4012
// The types tested are: bigs.
41-
// The ops tested are: xchg, cmpxchg.
13+
// The ops tested are: cmpxchg.
14+
// TODO: Test load/store, xchg.
15+
//
16+
// Please read the README before contributing.
4217
//
4318
//===----------------------------------------------------------------------===//
4419

@@ -55,8 +30,7 @@ struct big_t {
5530

5631
// The big struct cmpxchg test is identical to the numeric cmpxchg test, except
5732
// each element of the underlying array is incremented.
58-
void looper_big_cmpxchg(big_t *abig, big_t *bbig, int success_model,
59-
int fail_model) {
33+
void looper_big_cmpxchg(big_t *abig, int success_model, int fail_model) {
6034
for (int n = 0; n < kIterations; ++n) {
6135
big_t desired, expected = {};
6236
do {
@@ -65,8 +39,6 @@ void looper_big_cmpxchg(big_t *abig, big_t *bbig, int success_model,
6539
desired.v[k]++;
6640
} while (!__atomic_compare_exchange(abig, &expected, &desired, true,
6741
success_model, fail_model));
68-
for (int k = 0; k < kBigSize; ++k)
69-
bbig->v[k]++;
7042
}
7143
}
7244

@@ -75,15 +47,14 @@ void test_big_cmpxchg() {
7547

7648
for (int success_model : atomic_compare_exchange_models) {
7749
for (int fail_model : atomic_compare_exchange_models) {
78-
big_t abig = {}, bbig = {};
50+
big_t abig = {};
7951
for (int n = 0; n < kThreads; ++n)
80-
pool.emplace_back(looper_big_cmpxchg, &abig, &bbig,
81-
success_model, fail_model);
52+
pool.emplace_back(looper_big_cmpxchg, &abig, success_model, fail_model);
8253
for (int n = 0; n < kThreads; ++n)
8354
pool[n].join();
8455
pool.clear();
8556
for (int n = 0; n < kBigSize; ++n)
86-
if (lt(abig.v[n], bbig.v[n]) || abig.v[n] != kExpected)
57+
if (abig.v[n] != kExpected)
8758
fail();
8859
}
8960
}

SingleSource/UnitTests/Atomic/float_test.cpp

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,14 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// The following text is present in each test file:
10-
//
11-
// These tests aim to capture real-world multithreaded use cases of atomic
12-
// builtins. Each test focuses on a single atomic operation. Those using
13-
// multiple operations can be compared with other tests using the same
14-
// operations to isolate bugs to a single atomic operation.
15-
//
16-
// Each test consists of a "looper" body and a test script. The test script
17-
// instantiates 10 threads, each running the looper. The loopers contend the
18-
// same memory address, performing atomic operations on it. Each looper executes
19-
// 10^6 times for a total of 10^7 operations. The resultant value in the
20-
// contended pointer is compared against a closed-form solution. It's expected
21-
// that the two values equate.
22-
//
23-
// For example, a looper that increments the shared pointer is expected to end
24-
// up with a value of 10^7. If its final value is not that, the test fails.
25-
//
26-
// Each test also tests the corresponding nonatomic operation with a separate
27-
// shared variable. Ideally, this value differs from the atomic "correct" value,
28-
// and the test can compare the two. In reality, some simpler operations (e.g.
29-
// those conducted through the ALU) can still end up with the correct answer,
30-
// even when performed nonatomically. These tests do not check the nonatomic
31-
// result, although it is still outputted to aid in debugging.
32-
//
33-
// Each test is performed on all relevant types.
34-
//
35-
//===----------------------------------------------------------------------===//
36-
//
379
// This file tests atomic operations on floating point types with aligned
3810
// memory addresses.
3911
//
4012
// The types tested are: float, double.
4113
// The ops tested are: xchg, cmpxchg.
4214
//
15+
// Please read the README before contributing.
16+
//
4317
//===----------------------------------------------------------------------===//
4418

4519
#include <sys/stat.h>
@@ -59,18 +33,13 @@ void test_float_scalar_xchg() {
5933
std::vector<std::thread> pool;
6034

6135
for (int model : atomic_exchange_models) {
62-
T afloat = 0, ffloat = 0;
36+
T afloat = 0;
6337
for (int n = 0; n < kThreads; ++n)
6438
pool.emplace_back(looper_numeric_xchg_atomic<T>, &afloat, model);
6539
for (int n = 0; n < kThreads; ++n)
6640
pool[n].join();
6741
pool.clear();
68-
for (int n = 0; n < kThreads; ++n)
69-
pool.emplace_back(looper_numeric_xchg_nonatomic<T>, &ffloat, model);
70-
for (int n = 0; n < kThreads; ++n)
71-
pool[n].join();
72-
pool.clear();
73-
if (lt(afloat, ffloat) || afloat < expected * (1 - kEpsilon) ||
42+
if (afloat < expected * (1 - kEpsilon) ||
7443
afloat > expected * (1 + kEpsilon))
7544
fail();
7645
}
@@ -85,14 +54,14 @@ void test_float_scalar_cmpxchg() {
8554

8655
for (int success_model : atomic_compare_exchange_models) {
8756
for (int fail_model : atomic_compare_exchange_models) {
88-
T afloat = 0, ffloat = 0;
57+
T afloat = 0;
8958
for (int n = 0; n < kThreads; ++n)
90-
pool.emplace_back(looper_numeric_cmpxchg<T>, &afloat, &ffloat,
91-
success_model, fail_model);
59+
pool.emplace_back(looper_numeric_cmpxchg<T>, &afloat, success_model,
60+
fail_model);
9261
for (int n = 0; n < kThreads; ++n)
9362
pool[n].join();
9463
pool.clear();
95-
if (lt(afloat, ffloat) || afloat < expected * (1 - kEpsilon) ||
64+
if (afloat < expected * (1 - kEpsilon) ||
9665
afloat > expected * (1 + kEpsilon))
9766
fail();
9867
}
@@ -107,6 +76,10 @@ void test_floating_point() {
10776
std::cout << "Testing double\n";
10877
test_float_scalar_xchg<double>();
10978
test_float_scalar_cmpxchg<double>();
79+
80+
std::cout << "Testing float128\n";
81+
test_float_scalar_xchg<__float128>();
82+
test_float_scalar_cmpxchg<__float128>();
11083
}
11184

11285
int main() {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
10 threads; 1000000 iterations each; total of 10000000
22
Testing float
33
Testing double
4+
Testing float128
45
PASSED
56
exit 0

0 commit comments

Comments
 (0)