Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Side by Side Diff: mojo/edk/util/waitable_event_unittest.cc

Issue 1408003013: Reland "EDK: Move //mojo/edk/system/waitable_event* to edk/util." (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/edk/util/waitable_event.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/edk/system/waitable_event.h" 5 #include "mojo/edk/util/waitable_event.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 9
10 #include <atomic> 10 #include <atomic>
11 #include <thread> 11 #include <thread>
12 #include <type_traits> 12 #include <type_traits>
13 #include <vector> 13 #include <vector>
14 14
15 #include "mojo/edk/system/test/sleep.h" 15 #include "mojo/edk/system/test/sleep.h"
16 #include "mojo/edk/system/test/stopwatch.h" 16 #include "mojo/edk/system/test/stopwatch.h"
17 #include "mojo/edk/system/test/timeouts.h" 17 #include "mojo/edk/system/test/timeouts.h"
18 #include "mojo/public/cpp/system/macros.h" 18 #include "mojo/public/cpp/system/macros.h"
19 #include "testing/gtest/include/gtest/gtest.h" 19 #include "testing/gtest/include/gtest/gtest.h"
20 20
21 using mojo::system::test::ActionTimeout;
22 using mojo::system::test::DeadlineFromMilliseconds;
23 using mojo::system::test::EpsilonTimeout;
24 using mojo::system::test::Sleep;
25 using mojo::system::test::SleepMilliseconds;
26 using mojo::system::test::Stopwatch;
27 using mojo::system::test::TinyTimeout;
28
21 namespace mojo { 29 namespace mojo {
22 namespace system { 30 namespace util {
23 namespace { 31 namespace {
24 32
25 // Sleeps for a "very small" amount of time. 33 // Sleeps for a "very small" amount of time.
26 void EpsilonRandomSleep() { 34 void EpsilonRandomSleep() {
27 test::SleepMilliseconds(static_cast<unsigned>(rand()) % 20u); 35 SleepMilliseconds(static_cast<unsigned>(rand()) % 20u);
28 } 36 }
29 37
30 // We'll use |MojoDeadline| with |uint64_t| (for |WaitWithTimeout()|'s timeout 38 // We'll use |MojoDeadline| with |uint64_t| (for |WaitWithTimeout()|'s timeout
31 // argument), though note that |WaitWithTimeout()| doesn't support 39 // argument), though note that |WaitWithTimeout()| doesn't support
32 // |MOJO_DEADLINE_INDEFINITE|. 40 // |MOJO_DEADLINE_INDEFINITE|.
33 static_assert(std::is_same<uint64_t, MojoDeadline>::value, 41 static_assert(std::is_same<uint64_t, MojoDeadline>::value,
34 "MojoDeadline isn't uint64_t!"); 42 "MojoDeadline isn't uint64_t!");
35 43
36 // AutoResetWaitableEvent ------------------------------------------------------ 44 // AutoResetWaitableEvent ------------------------------------------------------
37 45
38 TEST(AutoResetWaitableEventTest, Basic) { 46 TEST(AutoResetWaitableEventTest, Basic) {
39 AutoResetWaitableEvent ev; 47 AutoResetWaitableEvent ev;
40 EXPECT_FALSE(ev.IsSignaledForTest()); 48 EXPECT_FALSE(ev.IsSignaledForTest());
41 ev.Signal(); 49 ev.Signal();
42 EXPECT_TRUE(ev.IsSignaledForTest()); 50 EXPECT_TRUE(ev.IsSignaledForTest());
43 ev.Wait(); 51 ev.Wait();
44 EXPECT_FALSE(ev.IsSignaledForTest()); 52 EXPECT_FALSE(ev.IsSignaledForTest());
45 ev.Reset(); 53 ev.Reset();
46 EXPECT_FALSE(ev.IsSignaledForTest()); 54 EXPECT_FALSE(ev.IsSignaledForTest());
47 ev.Signal(); 55 ev.Signal();
48 EXPECT_TRUE(ev.IsSignaledForTest()); 56 EXPECT_TRUE(ev.IsSignaledForTest());
49 ev.Reset(); 57 ev.Reset();
50 EXPECT_FALSE(ev.IsSignaledForTest()); 58 EXPECT_FALSE(ev.IsSignaledForTest());
51 EXPECT_TRUE(ev.WaitWithTimeout(0)); 59 EXPECT_TRUE(ev.WaitWithTimeout(0));
52 EXPECT_FALSE(ev.IsSignaledForTest()); 60 EXPECT_FALSE(ev.IsSignaledForTest());
53 EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1))); 61 EXPECT_TRUE(ev.WaitWithTimeout(DeadlineFromMilliseconds(1)));
54 EXPECT_FALSE(ev.IsSignaledForTest()); 62 EXPECT_FALSE(ev.IsSignaledForTest());
55 ev.Signal(); 63 ev.Signal();
56 EXPECT_TRUE(ev.IsSignaledForTest()); 64 EXPECT_TRUE(ev.IsSignaledForTest());
57 EXPECT_FALSE(ev.WaitWithTimeout(0)); 65 EXPECT_FALSE(ev.WaitWithTimeout(0));
58 EXPECT_FALSE(ev.IsSignaledForTest()); 66 EXPECT_FALSE(ev.IsSignaledForTest());
59 EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1))); 67 EXPECT_TRUE(ev.WaitWithTimeout(DeadlineFromMilliseconds(1)));
60 EXPECT_FALSE(ev.IsSignaledForTest()); 68 EXPECT_FALSE(ev.IsSignaledForTest());
61 ev.Signal(); 69 ev.Signal();
62 EXPECT_FALSE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1))); 70 EXPECT_FALSE(ev.WaitWithTimeout(DeadlineFromMilliseconds(1)));
63 EXPECT_FALSE(ev.IsSignaledForTest()); 71 EXPECT_FALSE(ev.IsSignaledForTest());
64 } 72 }
65 73
66 TEST(AutoResetWaitableEventTest, MultipleWaiters) { 74 TEST(AutoResetWaitableEventTest, MultipleWaiters) {
67 AutoResetWaitableEvent ev; 75 AutoResetWaitableEvent ev;
68 76
69 for (size_t i = 0u; i < 5u; i++) { 77 for (size_t i = 0u; i < 5u; i++) {
70 std::atomic_uint wake_count(0u); 78 std::atomic_uint wake_count(0u);
71 std::vector<std::thread> threads; 79 std::vector<std::thread> threads;
72 for (size_t j = 0u; j < 4u; j++) { 80 for (size_t j = 0u; j < 4u; j++) {
73 threads.push_back(std::thread([&ev, &wake_count]() { 81 threads.push_back(std::thread([&ev, &wake_count]() {
74 if (rand() % 2 == 0) 82 if (rand() % 2 == 0)
75 ev.Wait(); 83 ev.Wait();
76 else 84 else
77 EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout())); 85 EXPECT_FALSE(ev.WaitWithTimeout(ActionTimeout()));
78 wake_count.fetch_add(1u); 86 wake_count.fetch_add(1u);
79 // Note: We can't say anything about the signaled state of |ev| here, 87 // Note: We can't say anything about the signaled state of |ev| here,
80 // since the main thread may have already signaled it again. 88 // since the main thread may have already signaled it again.
81 })); 89 }));
82 } 90 }
83 91
84 // Unfortunately, we can't really wait for the threads to be waiting, so we 92 // Unfortunately, we can't really wait for the threads to be waiting, so we
85 // just sleep for a bit, and count on them having started and advanced to 93 // just sleep for a bit, and count on them having started and advanced to
86 // waiting. 94 // waiting.
87 test::Sleep(2 * test::TinyTimeout()); 95 Sleep(2 * TinyTimeout());
88 96
89 for (size_t j = 0u; j < threads.size(); j++) { 97 for (size_t j = 0u; j < threads.size(); j++) {
90 unsigned old_wake_count = wake_count.load(); 98 unsigned old_wake_count = wake_count.load();
91 EXPECT_EQ(j, old_wake_count); 99 EXPECT_EQ(j, old_wake_count);
92 100
93 // Each |Signal()| should wake exactly one thread. 101 // Each |Signal()| should wake exactly one thread.
94 ev.Signal(); 102 ev.Signal();
95 103
96 // Poll for |wake_count| to change. 104 // Poll for |wake_count| to change.
97 while (wake_count.load() == old_wake_count) 105 while (wake_count.load() == old_wake_count)
98 test::Sleep(test::EpsilonTimeout()); 106 Sleep(EpsilonTimeout());
99 107
100 EXPECT_FALSE(ev.IsSignaledForTest()); 108 EXPECT_FALSE(ev.IsSignaledForTest());
101 109
102 // And once it's changed, wait a little longer, to see if any other 110 // And once it's changed, wait a little longer, to see if any other
103 // threads are awoken (they shouldn't be). 111 // threads are awoken (they shouldn't be).
104 test::Sleep(test::EpsilonTimeout()); 112 Sleep(EpsilonTimeout());
105 113
106 EXPECT_EQ(old_wake_count + 1u, wake_count.load()); 114 EXPECT_EQ(old_wake_count + 1u, wake_count.load());
107 115
108 EXPECT_FALSE(ev.IsSignaledForTest()); 116 EXPECT_FALSE(ev.IsSignaledForTest());
109 } 117 }
110 118
111 // Having done that, if we signal |ev| now, it should stay signaled. 119 // Having done that, if we signal |ev| now, it should stay signaled.
112 ev.Signal(); 120 ev.Signal();
113 test::Sleep(test::EpsilonTimeout()); 121 Sleep(EpsilonTimeout());
114 EXPECT_TRUE(ev.IsSignaledForTest()); 122 EXPECT_TRUE(ev.IsSignaledForTest());
115 123
116 for (auto& thread : threads) 124 for (auto& thread : threads)
117 thread.join(); 125 thread.join();
118 126
119 ev.Reset(); 127 ev.Reset();
120 } 128 }
121 } 129 }
122 130
123 TEST(AutoResetWaitableEventTest, Timeouts) { 131 TEST(AutoResetWaitableEventTest, Timeouts) {
124 static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80}; 132 static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80};
125 133
126 test::Stopwatch stopwatch; 134 Stopwatch stopwatch;
127 135
128 AutoResetWaitableEvent ev; 136 AutoResetWaitableEvent ev;
129 137
130 for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) { 138 for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) {
131 uint64_t timeout = test::DeadlineFromMilliseconds(kTestTimeoutsMs[i]); 139 uint64_t timeout = DeadlineFromMilliseconds(kTestTimeoutsMs[i]);
132 140
133 stopwatch.Start(); 141 stopwatch.Start();
134 EXPECT_TRUE(ev.WaitWithTimeout(timeout)); 142 EXPECT_TRUE(ev.WaitWithTimeout(timeout));
135 MojoDeadline elapsed = stopwatch.Elapsed(); 143 MojoDeadline elapsed = stopwatch.Elapsed();
136 144
137 // It should time out after *at least* the specified amount of time. 145 // It should time out after *at least* the specified amount of time.
138 EXPECT_GE(elapsed, timeout); 146 EXPECT_GE(elapsed, timeout);
139 // But we expect that it should time out soon after that amount of time. 147 // But we expect that it should time out soon after that amount of time.
140 EXPECT_LT(elapsed, timeout + test::EpsilonTimeout()); 148 EXPECT_LT(elapsed, timeout + EpsilonTimeout());
141 } 149 }
142 } 150 }
143 151
144 // ManualResetWaitableEvent ---------------------------------------------------- 152 // ManualResetWaitableEvent ----------------------------------------------------
145 153
146 TEST(ManualResetWaitableEventTest, Basic) { 154 TEST(ManualResetWaitableEventTest, Basic) {
147 ManualResetWaitableEvent ev; 155 ManualResetWaitableEvent ev;
148 EXPECT_FALSE(ev.IsSignaledForTest()); 156 EXPECT_FALSE(ev.IsSignaledForTest());
149 ev.Signal(); 157 ev.Signal();
150 EXPECT_TRUE(ev.IsSignaledForTest()); 158 EXPECT_TRUE(ev.IsSignaledForTest());
151 ev.Wait(); 159 ev.Wait();
152 EXPECT_TRUE(ev.IsSignaledForTest()); 160 EXPECT_TRUE(ev.IsSignaledForTest());
153 ev.Reset(); 161 ev.Reset();
154 EXPECT_FALSE(ev.IsSignaledForTest()); 162 EXPECT_FALSE(ev.IsSignaledForTest());
155 EXPECT_TRUE(ev.WaitWithTimeout(0)); 163 EXPECT_TRUE(ev.WaitWithTimeout(0));
156 EXPECT_FALSE(ev.IsSignaledForTest()); 164 EXPECT_FALSE(ev.IsSignaledForTest());
157 EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1))); 165 EXPECT_TRUE(ev.WaitWithTimeout(DeadlineFromMilliseconds(1)));
158 EXPECT_FALSE(ev.IsSignaledForTest()); 166 EXPECT_FALSE(ev.IsSignaledForTest());
159 ev.Signal(); 167 ev.Signal();
160 EXPECT_TRUE(ev.IsSignaledForTest()); 168 EXPECT_TRUE(ev.IsSignaledForTest());
161 EXPECT_FALSE(ev.WaitWithTimeout(0)); 169 EXPECT_FALSE(ev.WaitWithTimeout(0));
162 EXPECT_TRUE(ev.IsSignaledForTest()); 170 EXPECT_TRUE(ev.IsSignaledForTest());
163 EXPECT_FALSE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1))); 171 EXPECT_FALSE(ev.WaitWithTimeout(DeadlineFromMilliseconds(1)));
164 EXPECT_TRUE(ev.IsSignaledForTest()); 172 EXPECT_TRUE(ev.IsSignaledForTest());
165 } 173 }
166 174
167 TEST(ManualResetWaitableEventTest, SignalMultiple) { 175 TEST(ManualResetWaitableEventTest, SignalMultiple) {
168 ManualResetWaitableEvent ev; 176 ManualResetWaitableEvent ev;
169 177
170 for (size_t i = 0u; i < 10u; i++) { 178 for (size_t i = 0u; i < 10u; i++) {
171 for (size_t num_waiters = 1u; num_waiters < 5u; num_waiters++) { 179 for (size_t num_waiters = 1u; num_waiters < 5u; num_waiters++) {
172 std::vector<std::thread> threads; 180 std::vector<std::thread> threads;
173 for (size_t j = 0u; j < num_waiters; j++) { 181 for (size_t j = 0u; j < num_waiters; j++) {
174 threads.push_back(std::thread([&ev]() { 182 threads.push_back(std::thread([&ev]() {
175 EpsilonRandomSleep(); 183 EpsilonRandomSleep();
176 184
177 if (rand() % 2 == 0) 185 if (rand() % 2 == 0)
178 ev.Wait(); 186 ev.Wait();
179 else 187 else
180 EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout())); 188 EXPECT_FALSE(ev.WaitWithTimeout(ActionTimeout()));
181 })); 189 }));
182 } 190 }
183 191
184 EpsilonRandomSleep(); 192 EpsilonRandomSleep();
185 193
186 ev.Signal(); 194 ev.Signal();
187 195
188 // The threads will only terminate once they've successfully waited (or 196 // The threads will only terminate once they've successfully waited (or
189 // timed out). 197 // timed out).
190 for (auto& thread : threads) 198 for (auto& thread : threads)
191 thread.join(); 199 thread.join();
192 200
193 ev.Reset(); 201 ev.Reset();
194 } 202 }
195 } 203 }
196 } 204 }
197 205
198 // Tries to test that threads that are awoken may immediately call |Reset()| 206 // Tries to test that threads that are awoken may immediately call |Reset()|
199 // without affecting other threads that are awoken. 207 // without affecting other threads that are awoken.
200 TEST(ManualResetWaitableEventTest, SignalMultipleWaitReset) { 208 TEST(ManualResetWaitableEventTest, SignalMultipleWaitReset) {
201 ManualResetWaitableEvent ev; 209 ManualResetWaitableEvent ev;
202 210
203 for (size_t i = 0u; i < 5u; i++) { 211 for (size_t i = 0u; i < 5u; i++) {
204 std::vector<std::thread> threads; 212 std::vector<std::thread> threads;
205 for (size_t j = 0u; j < 4u; j++) { 213 for (size_t j = 0u; j < 4u; j++) {
206 threads.push_back(std::thread([&ev]() { 214 threads.push_back(std::thread([&ev]() {
207 if (rand() % 2 == 0) 215 if (rand() % 2 == 0)
208 ev.Wait(); 216 ev.Wait();
209 else 217 else
210 EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout())); 218 EXPECT_FALSE(ev.WaitWithTimeout(ActionTimeout()));
211 ev.Reset(); 219 ev.Reset();
212 })); 220 }));
213 } 221 }
214 222
215 // Unfortunately, we can't really wait for the threads to be waiting, so we 223 // Unfortunately, we can't really wait for the threads to be waiting, so we
216 // just sleep for a bit, and count on them having started and advanced to 224 // just sleep for a bit, and count on them having started and advanced to
217 // waiting. 225 // waiting.
218 test::Sleep(2 * test::TinyTimeout()); 226 Sleep(2 * TinyTimeout());
219 227
220 ev.Signal(); 228 ev.Signal();
221 229
222 // In fact, we may ourselves call |Reset()| immediately. 230 // In fact, we may ourselves call |Reset()| immediately.
223 ev.Reset(); 231 ev.Reset();
224 232
225 // The threads will only terminate once they've successfully waited (or 233 // The threads will only terminate once they've successfully waited (or
226 // timed out). 234 // timed out).
227 for (auto& thread : threads) 235 for (auto& thread : threads)
228 thread.join(); 236 thread.join();
229 237
230 ASSERT_FALSE(ev.IsSignaledForTest()); 238 ASSERT_FALSE(ev.IsSignaledForTest());
231 } 239 }
232 } 240 }
233 241
234 TEST(ManualResetWaitableEventTest, Timeouts) { 242 TEST(ManualResetWaitableEventTest, Timeouts) {
235 static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80}; 243 static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80};
236 244
237 test::Stopwatch stopwatch; 245 Stopwatch stopwatch;
238 246
239 ManualResetWaitableEvent ev; 247 ManualResetWaitableEvent ev;
240 248
241 for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) { 249 for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) {
242 uint64_t timeout = test::DeadlineFromMilliseconds(kTestTimeoutsMs[i]); 250 uint64_t timeout = DeadlineFromMilliseconds(kTestTimeoutsMs[i]);
243 251
244 stopwatch.Start(); 252 stopwatch.Start();
245 EXPECT_TRUE(ev.WaitWithTimeout(timeout)); 253 EXPECT_TRUE(ev.WaitWithTimeout(timeout));
246 MojoDeadline elapsed = stopwatch.Elapsed(); 254 MojoDeadline elapsed = stopwatch.Elapsed();
247 255
248 // It should time out after *at least* the specified amount of time. 256 // It should time out after *at least* the specified amount of time.
249 EXPECT_GE(elapsed, timeout); 257 EXPECT_GE(elapsed, timeout);
250 // But we expect that it should time out soon after that amount of time. 258 // But we expect that it should time out soon after that amount of time.
251 EXPECT_LT(elapsed, timeout + test::EpsilonTimeout()); 259 EXPECT_LT(elapsed, timeout + EpsilonTimeout());
252 } 260 }
253 } 261 }
254 262
255 } // namespace 263 } // namespace
256 } // namespace system 264 } // namespace util
257 } // namespace mojo 265 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/edk/util/waitable_event.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698