add an implementation of python-style events
This is another synchronization primitive. It will be used in a couple
of extra tests coming right after this.
Change-Id: I536f04f0b5f4f87a0c0a4c8e531c526c7a56bb49
diff --git a/aos/common/event_test.cc b/aos/common/event_test.cc
new file mode 100644
index 0000000..fff7522
--- /dev/null
+++ b/aos/common/event_test.cc
@@ -0,0 +1,66 @@
+#include "aos/common/event.h"
+
+#include <thread>
+
+#include "gtest/gtest.h"
+
+#include "aos/common/queue_testutils.h"
+#include "aos/common/time.h"
+
+namespace aos {
+namespace testing {
+
+class EventTest : public ::testing::Test {
+ public:
+ Event test_event;
+
+ protected:
+ void SetUp() override {
+ ::aos::common::testing::EnableTestLogging();
+ }
+};
+
+// Makes sure that basic operations with no blocking or anything work.
+TEST_F(EventTest, Basic) {
+ EXPECT_FALSE(test_event.Clear());
+ EXPECT_FALSE(test_event.Clear());
+
+ test_event.Set();
+ test_event.Wait();
+ EXPECT_TRUE(test_event.Clear());
+ EXPECT_FALSE(test_event.Clear());
+}
+
+// Tests that tsan understands that events establish a happens-before
+// relationship.
+TEST_F(EventTest, ThreadSanitizer) {
+ for (int i = 0; i < 1000; ++i) {
+ int variable = 0;
+ ::std::thread thread([this, &variable]() {
+ test_event.Wait();
+ --variable;
+ });
+ ++variable;
+ test_event.Set();
+ thread.join();
+ EXPECT_EQ(0, variable);
+ }
+}
+
+// Tests that an event blocks correctly.
+TEST_F(EventTest, Blocks) {
+ time::Time start_time, finish_time;
+ ::std::thread thread([this, &start_time, &finish_time]() {
+ start_time = time::Time::Now();
+ test_event.Wait();
+ finish_time = time::Time::Now();
+ });
+ static const time::Time kWaitTime = time::Time::InSeconds(0.05);
+ time::SleepFor(kWaitTime);
+ test_event.Set();
+ thread.join();
+ EXPECT_GE(finish_time - start_time, kWaitTime);
+}
+
+} // namespace testing
+} // namespace aos