diff options
| author | Jules Blok <jules.blok@gmail.com> | 2015-06-10 00:00:12 +0200 |
|---|---|---|
| committer | Jules Blok <jules.blok@gmail.com> | 2015-06-10 00:00:12 +0200 |
| commit | 7dfced21a2e5aac7195e0e1ad76468e30306766b (patch) | |
| tree | bd671b639d3d911460b767caabad8fc8a759a6bf /Source/UnitTests/Common/FlagTest.cpp | |
| parent | c25be031fc1031d795157d8344b87b7841145197 (diff) | |
| parent | 7b0a65e295c784f9d573f2ef52d4e2a7b9bb2889 (diff) | |
Merge branch 'master' into stable
Diffstat (limited to 'Source/UnitTests/Common/FlagTest.cpp')
| -rw-r--r-- | Source/UnitTests/Common/FlagTest.cpp | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/Source/UnitTests/Common/FlagTest.cpp b/Source/UnitTests/Common/FlagTest.cpp new file mode 100644 index 0000000000..8d43d10791 --- /dev/null +++ b/Source/UnitTests/Common/FlagTest.cpp @@ -0,0 +1,91 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include <array> +#include <thread> +#include <gtest/gtest.h> + +#include "Common/Flag.h" + +using Common::Flag; + +TEST(Flag, Simple) +{ + Flag f; + EXPECT_FALSE(f.IsSet()); + + f.Set(); + EXPECT_TRUE(f.IsSet()); + + f.Clear(); + EXPECT_FALSE(f.IsSet()); + + f.Set(false); + EXPECT_FALSE(f.IsSet()); + + EXPECT_TRUE(f.TestAndSet()); + EXPECT_TRUE(f.TestAndClear()); + + Flag f2(true); + EXPECT_TRUE(f2.IsSet()); +} + +TEST(Flag, MultiThreaded) +{ + Flag f; + int count = 0; + const int ITERATIONS_COUNT = 100000; + + auto setter = [&]() { + for (int i = 0; i < ITERATIONS_COUNT; ++i) + { + while (f.IsSet()); + f.Set(); + } + }; + + auto clearer = [&]() { + for (int i = 0; i < ITERATIONS_COUNT; ++i) + { + while (!f.IsSet()); + count++; + f.Clear(); + } + }; + + std::thread setter_thread(setter); + std::thread clearer_thread(clearer); + + setter_thread.join(); + clearer_thread.join(); + + EXPECT_EQ(ITERATIONS_COUNT, count); +} + +TEST(Flag, SpinLock) +{ + // Uses a flag to implement basic spinlocking using TestAndSet. + Flag f; + int count = 0; + const int ITERATIONS_COUNT = 5000; + const int THREADS_COUNT = 50; + + auto adder_func = [&]() { + for (int i = 0; i < ITERATIONS_COUNT; ++i) + { + // Acquire the spinlock. + while (!f.TestAndSet()); + count++; + f.Clear(); + } + }; + + std::array<std::thread, THREADS_COUNT> threads; + for (auto& th : threads) + th = std::thread(adder_func); + for (auto& th : threads) + th.join(); + + EXPECT_EQ(ITERATIONS_COUNT * THREADS_COUNT, count); +} |
