From 6bdcbad3e4488c85ae402dcb44f65005769c64b9 Mon Sep 17 00:00:00 2001 From: Pierre Bourdon Date: Mon, 14 Apr 2014 01:15:23 +0200 Subject: [PATCH] Common: Move the Event class to a separate file, and add tests for it. Fix includes everywhere to match this. --- Source/Core/AudioCommon/AOSoundStream.h | 4 +- Source/Core/AudioCommon/DSoundStream.cpp | 2 + Source/Core/AudioCommon/DSoundStream.h | 3 +- Source/Core/AudioCommon/OpenALStream.cpp | 2 + Source/Core/AudioCommon/OpenALStream.h | 3 +- Source/Core/AudioCommon/OpenSLESStream.h | 3 +- Source/Core/AudioCommon/XAudio2Stream.cpp | 1 + Source/Core/AudioCommon/XAudio2Stream.h | 2 +- Source/Core/AudioCommon/XAudio2_7Stream.cpp | 1 + Source/Core/AudioCommon/XAudio2_7Stream.h | 2 +- Source/Core/Common/Event.h | 59 +++++++++++++++++++++ Source/Core/Common/Thread.h | 39 -------------- Source/Core/Core/DSP/DSPCore.cpp | 2 +- Source/Core/Core/HW/CPU.cpp | 3 +- Source/Core/Core/HW/DSPLLE/DSPLLE.cpp | 4 +- Source/Core/Core/State.cpp | 4 +- Source/Core/DolphinWX/Debugger/CodeWindow.h | 2 +- Source/Core/DolphinWX/Frame.h | 2 +- Source/Core/DolphinWX/MainAndroid.cpp | 2 +- Source/Core/DolphinWX/MainNoGUI.cpp | 2 +- Source/UnitTests/Common/CMakeLists.txt | 1 + Source/UnitTests/Common/EventTest.cpp | 42 +++++++++++++++ 22 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 Source/Core/Common/Event.h create mode 100644 Source/UnitTests/Common/EventTest.cpp diff --git a/Source/Core/AudioCommon/AOSoundStream.h b/Source/Core/AudioCommon/AOSoundStream.h index 5900a8c8b5..8d8cc5203e 100644 --- a/Source/Core/AudioCommon/AOSoundStream.h +++ b/Source/Core/AudioCommon/AOSoundStream.h @@ -5,7 +5,9 @@ #pragma once #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" +#include "Common/StdMutex.h" +#include "Common/StdThread.h" #if defined(HAVE_AO) && HAVE_AO #include diff --git a/Source/Core/AudioCommon/DSoundStream.cpp b/Source/Core/AudioCommon/DSoundStream.cpp index 2ffbe9794b..df96a9551f 100644 --- a/Source/Core/AudioCommon/DSoundStream.cpp +++ b/Source/Core/AudioCommon/DSoundStream.cpp @@ -9,6 +9,8 @@ #include "AudioCommon/AudioCommon.h" #include "AudioCommon/DSoundStream.h" +#include "Common/StdThread.h" +#include "Common/Thread.h" bool DSound::CreateBuffer() { diff --git a/Source/Core/AudioCommon/DSoundStream.h b/Source/Core/AudioCommon/DSoundStream.h index 331c4581d3..d885a17664 100644 --- a/Source/Core/AudioCommon/DSoundStream.h +++ b/Source/Core/AudioCommon/DSoundStream.h @@ -5,7 +5,8 @@ #pragma once #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" +#include "Common/StdThread.h" #ifdef _WIN32 #include diff --git a/Source/Core/AudioCommon/OpenALStream.cpp b/Source/Core/AudioCommon/OpenALStream.cpp index b2f820c453..1c1a802528 100644 --- a/Source/Core/AudioCommon/OpenALStream.cpp +++ b/Source/Core/AudioCommon/OpenALStream.cpp @@ -5,6 +5,8 @@ #include "AudioCommon/aldlist.h" #include "AudioCommon/DPL2Decoder.h" #include "AudioCommon/OpenALStream.h" +#include "Common/StdThread.h" +#include "Common/Thread.h" #if defined HAVE_OPENAL && HAVE_OPENAL diff --git a/Source/Core/AudioCommon/OpenALStream.h b/Source/Core/AudioCommon/OpenALStream.h index 0c3f932a38..940bb090f4 100644 --- a/Source/Core/AudioCommon/OpenALStream.h +++ b/Source/Core/AudioCommon/OpenALStream.h @@ -5,7 +5,8 @@ #pragma once #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" +#include "Common/StdThread.h" #include "Core/Core.h" #include "Core/HW/AudioInterface.h" #include "Core/HW/SystemTimers.h" diff --git a/Source/Core/AudioCommon/OpenSLESStream.h b/Source/Core/AudioCommon/OpenSLESStream.h index 08deec6eb1..9ba190728d 100644 --- a/Source/Core/AudioCommon/OpenSLESStream.h +++ b/Source/Core/AudioCommon/OpenSLESStream.h @@ -5,7 +5,8 @@ #pragma once #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" +#include "Common/StdThread.h" class OpenSLESStream final : public SoundStream { diff --git a/Source/Core/AudioCommon/XAudio2Stream.cpp b/Source/Core/AudioCommon/XAudio2Stream.cpp index d5964f0e0e..81af045300 100644 --- a/Source/Core/AudioCommon/XAudio2Stream.cpp +++ b/Source/Core/AudioCommon/XAudio2Stream.cpp @@ -5,6 +5,7 @@ #include #include "AudioCommon/AudioCommon.h" #include "AudioCommon/XAudio2Stream.h" +#include "Common/Event.h" #ifndef XAUDIO2_DLL #error You are building this module against the wrong version of DirectX. You probably need to remove DXSDK_DIR from your include path. diff --git a/Source/Core/AudioCommon/XAudio2Stream.h b/Source/Core/AudioCommon/XAudio2Stream.h index be76d919e8..9083abdc3b 100644 --- a/Source/Core/AudioCommon/XAudio2Stream.h +++ b/Source/Core/AudioCommon/XAudio2Stream.h @@ -11,7 +11,7 @@ #include #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" #ifdef _WIN32 diff --git a/Source/Core/AudioCommon/XAudio2_7Stream.cpp b/Source/Core/AudioCommon/XAudio2_7Stream.cpp index 816d83d47b..8739e919f5 100644 --- a/Source/Core/AudioCommon/XAudio2_7Stream.cpp +++ b/Source/Core/AudioCommon/XAudio2_7Stream.cpp @@ -9,6 +9,7 @@ #include "AudioCommon/AudioCommon.h" #include "AudioCommon/XAudio2_7Stream.h" +#include "Common/Event.h" #ifdef HAVE_DXSDK #include diff --git a/Source/Core/AudioCommon/XAudio2_7Stream.h b/Source/Core/AudioCommon/XAudio2_7Stream.h index e1e3182be9..99c0ca690f 100644 --- a/Source/Core/AudioCommon/XAudio2_7Stream.h +++ b/Source/Core/AudioCommon/XAudio2_7Stream.h @@ -14,7 +14,7 @@ #include #include "AudioCommon/SoundStream.h" -#include "Common/Thread.h" +#include "Common/Event.h" #ifdef _WIN32 diff --git a/Source/Core/Common/Event.h b/Source/Core/Common/Event.h new file mode 100644 index 0000000000..1203eb38c0 --- /dev/null +++ b/Source/Core/Common/Event.h @@ -0,0 +1,59 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +// Multithreaded event class. This allows waiting in a thread for an event to +// be triggered in another thread. While waiting, the CPU will be available for +// other tasks. +// * Set(): triggers the event and wakes up the waiting thread. +// * Wait(): waits for the event to be triggered. +// * Reset(): tries to reset the event before the waiting thread sees it was +// triggered. Usually a bad idea. + +#pragma once + +#include "Common/StdConditionVariable.h" +#include "Common/StdMutex.h" + +namespace Common { + +class Event +{ +public: + Event() + : is_set(false) + {} + + void Set() + { + std::lock_guard lk(m_mutex); + if (!is_set) + { + is_set = true; + m_condvar.notify_one(); + } + } + + void Wait() + { + std::unique_lock lk(m_mutex); + m_condvar.wait(lk, [&]{ return is_set; }); + is_set = false; + } + + void Reset() + { + std::unique_lock lk(m_mutex); + // no other action required, since wait loops on + // the predicate and any lingering signal will get + // cleared on the first iteration + is_set = false; + } + +private: + volatile bool is_set; + std::condition_variable m_condvar; + std::mutex m_mutex; +}; + +} // namespace Common diff --git a/Source/Core/Common/Thread.h b/Source/Core/Common/Thread.h index d108359dcd..54045caf26 100644 --- a/Source/Core/Common/Thread.h +++ b/Source/Core/Common/Thread.h @@ -32,45 +32,6 @@ int CurrentThreadId(); void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask); void SetCurrentThreadAffinity(u32 mask); -class Event -{ -public: - Event() - : is_set(false) - {} - - void Set() - { - std::lock_guard lk(m_mutex); - if (!is_set) - { - is_set = true; - m_condvar.notify_one(); - } - } - - void Wait() - { - std::unique_lock lk(m_mutex); - m_condvar.wait(lk, [&]{ return is_set; }); - is_set = false; - } - - void Reset() - { - std::unique_lock lk(m_mutex); - // no other action required, since wait loops on - // the predicate and any lingering signal will get - // cleared on the first iteration - is_set = false; - } - -private: - volatile bool is_set; - std::condition_variable m_condvar; - std::mutex m_mutex; -}; - // TODO: doesn't work on windows with (count > 2) class Barrier { diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index 520db9ac49..45063d4d47 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -24,10 +24,10 @@ ====================================================================*/ #include "Common/Common.h" +#include "Common/Event.h" #include "Common/FileUtil.h" #include "Common/Hash.h" #include "Common/MemoryUtil.h" -#include "Common/Thread.h" #include "Core/DSP/DSPAnalyzer.h" #include "Core/DSP/DSPCore.h" diff --git a/Source/Core/Core/HW/CPU.cpp b/Source/Core/Core/HW/CPU.cpp index 613974b675..820617eb33 100644 --- a/Source/Core/Core/HW/CPU.cpp +++ b/Source/Core/Core/HW/CPU.cpp @@ -5,7 +5,8 @@ #include "AudioCommon/AudioCommon.h" #include "Common/Common.h" -#include "Common/Thread.h" +#include "Common/Event.h" +#include "Common/StdMutex.h" #include "Core/Core.h" #include "Core/DSPEmulator.h" diff --git a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp index 697e69586d..8ada666527 100644 --- a/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp +++ b/Source/Core/Core/HW/DSPLLE/DSPLLE.cpp @@ -7,9 +7,11 @@ #include "Common/Common.h" #include "Common/CommonPaths.h" #include "Common/CPUDetect.h" +#include "Common/Event.h" #include "Common/IniFile.h" #include "Common/LogManager.h" -#include "Common/Thread.h" +#include "Common/StdMutex.h" +#include "Common/StdThread.h" #include "Core/ConfigManager.h" #include "Core/Core.h" diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 6d16cef7c5..f0060a4c70 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -5,8 +5,10 @@ #include #include "Common/Common.h" +#include "Common/Event.h" +#include "Common/StdMutex.h" +#include "Common/StdThread.h" #include "Common/StringUtil.h" -#include "Common/Thread.h" #include "Common/Timer.h" #include "Core/ConfigManager.h" diff --git a/Source/Core/DolphinWX/Debugger/CodeWindow.h b/Source/Core/DolphinWX/Debugger/CodeWindow.h index 90ddff938c..74977026ff 100644 --- a/Source/Core/DolphinWX/Debugger/CodeWindow.h +++ b/Source/Core/DolphinWX/Debugger/CodeWindow.h @@ -14,7 +14,7 @@ #include #include "Common/CommonTypes.h" -#include "Common/Thread.h" +#include "Common/Event.h" #include "DolphinWX/Globals.h" class CFrame; diff --git a/Source/Core/DolphinWX/Frame.h b/Source/Core/DolphinWX/Frame.h index 8f7e0732c7..2c98fda566 100644 --- a/Source/Core/DolphinWX/Frame.h +++ b/Source/Core/DolphinWX/Frame.h @@ -22,7 +22,7 @@ #include #include "Common/CommonTypes.h" -#include "Common/Thread.h" +#include "Common/Event.h" #include "DolphinWX/Globals.h" #include "InputCommon/GCPadStatus.h" diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index 4ce8ce0710..ab82e7def1 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -27,9 +27,9 @@ #include "Common/Common.h" #include "Common/CommonPaths.h" #include "Common/CPUDetect.h" +#include "Common/Event.h" #include "Common/FileUtil.h" #include "Common/LogManager.h" -#include "Common/Thread.h" #include "Core/BootManager.h" #include "Core/ConfigManager.h" #include "Core/Core.h" diff --git a/Source/Core/DolphinWX/MainNoGUI.cpp b/Source/Core/DolphinWX/MainNoGUI.cpp index c8f57f9ef6..cfd176e27a 100644 --- a/Source/Core/DolphinWX/MainNoGUI.cpp +++ b/Source/Core/DolphinWX/MainNoGUI.cpp @@ -10,8 +10,8 @@ #include #include "Common/Common.h" +#include "Common/Event.h" #include "Common/LogManager.h" -#include "Common/Thread.h" #include "Core/BootManager.h" #include "Core/ConfigManager.h" diff --git a/Source/UnitTests/Common/CMakeLists.txt b/Source/UnitTests/Common/CMakeLists.txt index 11fa2c57e0..42c0a8aaed 100644 --- a/Source/UnitTests/Common/CMakeLists.txt +++ b/Source/UnitTests/Common/CMakeLists.txt @@ -1,5 +1,6 @@ add_dolphin_test(BitFieldTest BitFieldTest.cpp common) add_dolphin_test(CommonFuncsTest CommonFuncsTest.cpp common) +add_dolphin_test(EventTest EventTest.cpp common) add_dolphin_test(FifoQueueTest FifoQueueTest.cpp common) add_dolphin_test(FixedSizeQueueTest FixedSizeQueueTest.cpp common) add_dolphin_test(FlagTest FlagTest.cpp common) diff --git a/Source/UnitTests/Common/EventTest.cpp b/Source/UnitTests/Common/EventTest.cpp new file mode 100644 index 0000000000..41949a893d --- /dev/null +++ b/Source/UnitTests/Common/EventTest.cpp @@ -0,0 +1,42 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include +#include + +#include "Common/Event.h" + +using Common::Event; + +TEST(Event, MultiThreaded) +{ + Event has_sent, can_send; + int shared_obj; + const int ITERATIONS_COUNT = 100000; + + auto sender = [&]() { + for (int i = 0; i < ITERATIONS_COUNT; ++i) + { + can_send.Wait(); + shared_obj = i; + has_sent.Set(); + } + }; + + auto receiver = [&]() { + for (int i = 0; i < ITERATIONS_COUNT; ++i) { + has_sent.Wait(); + EXPECT_EQ(i, shared_obj); + can_send.Set(); + } + }; + + std::thread sender_thread(sender); + std::thread receiver_thread(receiver); + + can_send.Set(); + + sender_thread.join(); + receiver_thread.join(); +}