proxygen
TearableTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
18 
19 #include <atomic>
20 #include <thread>
21 
23 
24 using namespace folly;
25 
26 namespace {
27 
28 struct Data {
29  Data(unsigned char value) {
30  setValue(value);
31  }
32 
33  void setValue(unsigned char value) {
34  for (auto& item : contents) {
35  item = value;
36  }
37  }
38 
39  void checkValue(unsigned char value) {
40  for (auto& item : contents) {
41  ASSERT_EQ(value, item);
42  }
43  }
44 
45  void checkValue2(unsigned char value1, unsigned char value2) {
46  for (auto& item : contents) {
47  ASSERT_TRUE(item == value1 || item == value2);
48  }
49  }
50 
51  // Note the odd size -- this will hopefully expose layout bugs under
52  // sanitizers.
53  unsigned char contents[99];
54 };
55 static_assert(is_trivially_copyable<Data>::value, "not trivially-copyable");
56 
57 TEST(TearableTest, BasicOperations) {
58  Tearable<Data> tearable;
59  Data src(0);
60  Data dst(1);
61  for (char c = 0; c < 10; ++c) {
62  src.setValue(c);
63  tearable.store(src);
64  tearable.load(dst);
65  dst.checkValue(c);
66  }
67 }
68 
69 TEST(TearableTest, Races) {
70  std::atomic<bool> stop(false);
71  Tearable<Data> tearable(Data(1));
72  std::thread write1([&]() {
73  Data data0(1);
74  while (!stop.load(std::memory_order_relaxed)) {
75  tearable.store(data0);
76  }
77  });
78  std::thread write2([&]() {
79  Data data1(2);
80  while (!stop.load(std::memory_order_relaxed)) {
81  tearable.store(data1);
82  }
83  });
84  Data val(0);
85  for (int i = 0; i < 100 * 1000; ++i) {
86  tearable.load(val);
87  val.checkValue2(1, 2);
88  }
89  stop.store(true, std::memory_order_relaxed);
90  write1.join();
91  write2.join();
92 }
93 
94 } // namespace
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
void load(T &dst) const
Definition: Tearable.h:65
double val
Definition: String.cpp:273
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
static void stop()
void store(const T &val)
Definition: Tearable.h:74
std::is_trivially_copyable< T > is_trivially_copyable
Definition: Traits.h:313
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
char c
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
TEST(SequencedExecutor, CPUThreadPoolExecutor)