mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-17 03:15:39 +00:00
Common: Remove Event
This commit is contained in:
parent
eb166220b1
commit
cb127b6412
|
@ -1,6 +1,5 @@
|
||||||
add_executable(common-tests
|
add_executable(common-tests
|
||||||
bitutils_tests.cpp
|
bitutils_tests.cpp
|
||||||
event_tests.cpp
|
|
||||||
file_system_tests.cpp
|
file_system_tests.cpp
|
||||||
path_tests.cpp
|
path_tests.cpp
|
||||||
rectangle_tests.cpp
|
rectangle_tests.cpp
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\dep\googletest\src\gtest_main.cc" />
|
<ClCompile Include="..\..\dep\googletest\src\gtest_main.cc" />
|
||||||
<ClCompile Include="bitutils_tests.cpp" />
|
<ClCompile Include="bitutils_tests.cpp" />
|
||||||
<ClCompile Include="event_tests.cpp" />
|
|
||||||
<ClCompile Include="file_system_tests.cpp" />
|
<ClCompile Include="file_system_tests.cpp" />
|
||||||
<ClCompile Include="path_tests.cpp" />
|
<ClCompile Include="path_tests.cpp" />
|
||||||
<ClCompile Include="rectangle_tests.cpp" />
|
<ClCompile Include="rectangle_tests.cpp" />
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\dep\googletest\src\gtest_main.cc" />
|
<ClCompile Include="..\..\dep\googletest\src\gtest_main.cc" />
|
||||||
<ClCompile Include="rectangle_tests.cpp" />
|
<ClCompile Include="rectangle_tests.cpp" />
|
||||||
<ClCompile Include="event_tests.cpp" />
|
|
||||||
<ClCompile Include="bitutils_tests.cpp" />
|
<ClCompile Include="bitutils_tests.cpp" />
|
||||||
<ClCompile Include="file_system_tests.cpp" />
|
<ClCompile Include="file_system_tests.cpp" />
|
||||||
<ClCompile Include="path_tests.cpp" />
|
<ClCompile Include="path_tests.cpp" />
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
#include "common/event.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
#include <atomic>
|
|
||||||
#include <chrono>
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
TEST(Event, InitialStateUnsignaled)
|
|
||||||
{
|
|
||||||
Common::Event e;
|
|
||||||
ASSERT_FALSE(e.TryWait(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, SignalOnSameThread)
|
|
||||||
{
|
|
||||||
Common::Event e;
|
|
||||||
e.Signal();
|
|
||||||
ASSERT_TRUE(e.TryWait(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, SignalOnSecondThread)
|
|
||||||
{
|
|
||||||
Common::Event e;
|
|
||||||
|
|
||||||
std::thread thr([&e]() { e.Signal(); });
|
|
||||||
e.Wait();
|
|
||||||
thr.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, SignalOnSecondThreadWithDelay)
|
|
||||||
{
|
|
||||||
Common::Event e;
|
|
||||||
std::atomic_bool fl{false};
|
|
||||||
|
|
||||||
std::thread thr([&e, &fl]() {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
e.Signal();
|
|
||||||
fl.store(true);
|
|
||||||
});
|
|
||||||
ASSERT_FALSE(fl.load());
|
|
||||||
e.Wait();
|
|
||||||
ASSERT_TRUE(fl.load());
|
|
||||||
thr.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, ResetAfterSignaling)
|
|
||||||
{
|
|
||||||
Common::Event e;
|
|
||||||
|
|
||||||
e.Signal();
|
|
||||||
e.Reset();
|
|
||||||
|
|
||||||
ASSERT_FALSE(e.TryWait(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, WaitForMultiple)
|
|
||||||
{
|
|
||||||
Common::Event e1, e2;
|
|
||||||
e1.Signal();
|
|
||||||
e2.Signal();
|
|
||||||
|
|
||||||
Common::Event* events[] = { &e1, &e2 };
|
|
||||||
Common::Event::WaitForMultiple(events, countof(events));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, AutoReset)
|
|
||||||
{
|
|
||||||
Common::Event e(true);
|
|
||||||
e.Signal();
|
|
||||||
ASSERT_TRUE(e.TryWait(1));
|
|
||||||
ASSERT_FALSE(e.TryWait(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Event, NoAutoReset)
|
|
||||||
{
|
|
||||||
Common::Event e(false);
|
|
||||||
e.Signal();
|
|
||||||
ASSERT_TRUE(e.TryWait(1));
|
|
||||||
ASSERT_TRUE(e.TryWait(1));
|
|
||||||
}
|
|
|
@ -11,8 +11,6 @@ add_library(common
|
||||||
dimensional_array.h
|
dimensional_array.h
|
||||||
error.cpp
|
error.cpp
|
||||||
error.h
|
error.h
|
||||||
event.cpp
|
|
||||||
event.h
|
|
||||||
fifo_queue.h
|
fifo_queue.h
|
||||||
file_system.cpp
|
file_system.cpp
|
||||||
file_system.h
|
file_system.h
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<ClInclude Include="dimensional_array.h" />
|
<ClInclude Include="dimensional_array.h" />
|
||||||
<ClInclude Include="easing.h" />
|
<ClInclude Include="easing.h" />
|
||||||
<ClInclude Include="error.h" />
|
<ClInclude Include="error.h" />
|
||||||
<ClInclude Include="event.h" />
|
|
||||||
<ClInclude Include="fifo_queue.h" />
|
<ClInclude Include="fifo_queue.h" />
|
||||||
<ClInclude Include="file_system.h" />
|
<ClInclude Include="file_system.h" />
|
||||||
<ClInclude Include="gl\context.h" />
|
<ClInclude Include="gl\context.h" />
|
||||||
|
@ -103,7 +102,6 @@
|
||||||
<ClCompile Include="d3d12\stream_buffer.cpp" />
|
<ClCompile Include="d3d12\stream_buffer.cpp" />
|
||||||
<ClCompile Include="d3d12\texture.cpp" />
|
<ClCompile Include="d3d12\texture.cpp" />
|
||||||
<ClCompile Include="d3d12\util.cpp" />
|
<ClCompile Include="d3d12\util.cpp" />
|
||||||
<ClCompile Include="event.cpp" />
|
|
||||||
<ClCompile Include="file_system.cpp" />
|
<ClCompile Include="file_system.cpp" />
|
||||||
<ClCompile Include="gl\context.cpp" />
|
<ClCompile Include="gl\context.cpp" />
|
||||||
<ClCompile Include="gl\context_wgl.cpp">
|
<ClCompile Include="gl\context_wgl.cpp">
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
<ClInclude Include="gl\shader_cache.h">
|
<ClInclude Include="gl\shader_cache.h">
|
||||||
<Filter>gl</Filter>
|
<Filter>gl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="event.h" />
|
|
||||||
<ClInclude Include="bitutils.h" />
|
<ClInclude Include="bitutils.h" />
|
||||||
<ClInclude Include="gl\context.h">
|
<ClInclude Include="gl\context.h">
|
||||||
<Filter>gl</Filter>
|
<Filter>gl</Filter>
|
||||||
|
@ -176,7 +175,6 @@
|
||||||
<ClCompile Include="gl\shader_cache.cpp">
|
<ClCompile Include="gl\shader_cache.cpp">
|
||||||
<Filter>gl</Filter>
|
<Filter>gl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="event.cpp" />
|
|
||||||
<ClCompile Include="gl\context_wgl.cpp">
|
<ClCompile Include="gl\context_wgl.cpp">
|
||||||
<Filter>gl</Filter>
|
<Filter>gl</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -1,253 +0,0 @@
|
||||||
#include "event.h"
|
|
||||||
#include "assert.h"
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#include "windows_headers.h"
|
|
||||||
#include <malloc.h>
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
|
||||||
#include <errno.h>
|
|
||||||
#include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(USE_WIN32_EVENT_OBJECTS)
|
|
||||||
|
|
||||||
Event::Event(bool auto_reset /* = false */)
|
|
||||||
{
|
|
||||||
m_event_handle = reinterpret_cast<void*>(CreateEvent(nullptr, auto_reset ? FALSE : TRUE, FALSE, nullptr));
|
|
||||||
Assert(m_event_handle != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event::~Event()
|
|
||||||
{
|
|
||||||
CloseHandle(reinterpret_cast<HANDLE>(m_event_handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Signal()
|
|
||||||
{
|
|
||||||
SetEvent(reinterpret_cast<HANDLE>(m_event_handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Wait()
|
|
||||||
{
|
|
||||||
WaitForSingleObject(reinterpret_cast<HANDLE>(m_event_handle), INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Event::TryWait(u32 timeout_in_ms)
|
|
||||||
{
|
|
||||||
return (WaitForSingleObject(reinterpret_cast<HANDLE>(m_event_handle), timeout_in_ms) == WAIT_OBJECT_0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Reset()
|
|
||||||
{
|
|
||||||
ResetEvent(reinterpret_cast<HANDLE>(m_event_handle));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::WaitForMultiple(Event** events, u32 num_events)
|
|
||||||
{
|
|
||||||
DebugAssert(num_events > 0);
|
|
||||||
|
|
||||||
HANDLE* event_handles = (HANDLE*)alloca(sizeof(HANDLE) * num_events);
|
|
||||||
for (u32 i = 0; i < num_events; i++)
|
|
||||||
event_handles[i] = reinterpret_cast<HANDLE>(events[i]->m_event_handle);
|
|
||||||
|
|
||||||
WaitForMultipleObjects(num_events, event_handles, TRUE, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
|
|
||||||
Event::Event(bool auto_reset /* = false */) : m_auto_reset(auto_reset)
|
|
||||||
{
|
|
||||||
InitializeCriticalSection(&m_cs);
|
|
||||||
InitializeConditionVariable(&m_cv);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event::~Event()
|
|
||||||
{
|
|
||||||
DeleteCriticalSection(&m_cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Signal()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&m_cs);
|
|
||||||
m_signaled.store(true);
|
|
||||||
WakeAllConditionVariable(&m_cv);
|
|
||||||
LeaveCriticalSection(&m_cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Wait()
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
EnterCriticalSection(&m_cs);
|
|
||||||
while (!m_signaled.load())
|
|
||||||
SleepConditionVariableCS(&m_cv, &m_cs, INFINITE);
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
|
|
||||||
LeaveCriticalSection(&m_cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Event::TryWait(u32 timeout_in_ms)
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
const u32 start = GetTickCount();
|
|
||||||
|
|
||||||
EnterCriticalSection(&m_cs);
|
|
||||||
while (!m_signaled.load() && (GetTickCount() - start) < timeout_in_ms)
|
|
||||||
SleepConditionVariableCS(&m_cv, &m_cs, timeout_in_ms);
|
|
||||||
|
|
||||||
const bool result = m_signaled.load();
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && result && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
|
|
||||||
LeaveCriticalSection(&m_cs);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Reset()
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&m_cs);
|
|
||||||
m_signaled.store(false);
|
|
||||||
LeaveCriticalSection(&m_cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::WaitForMultiple(Event** events, u32 num_events)
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < num_events; i++)
|
|
||||||
events[i]->Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
|
||||||
|
|
||||||
Event::Event(bool auto_reset /* = false */) : m_auto_reset(auto_reset)
|
|
||||||
{
|
|
||||||
pthread_mutex_init(&m_mutex, nullptr);
|
|
||||||
pthread_cond_init(&m_cv, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
Event::~Event()
|
|
||||||
{
|
|
||||||
pthread_cond_destroy(&m_cv);
|
|
||||||
pthread_mutex_destroy(&m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Signal()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&m_mutex);
|
|
||||||
m_signaled.store(true);
|
|
||||||
pthread_cond_broadcast(&m_cv);
|
|
||||||
pthread_mutex_unlock(&m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Wait()
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&m_mutex);
|
|
||||||
while (!m_signaled.load())
|
|
||||||
pthread_cond_wait(&m_cv, &m_mutex);
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Event::TryWait(u32 timeout_in_ms)
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
struct timespec ts;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &ts);
|
|
||||||
ts.tv_sec += timeout_in_ms / 1000;
|
|
||||||
ts.tv_nsec += (timeout_in_ms % 1000) * 1000000;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&m_mutex);
|
|
||||||
while (!m_signaled.load())
|
|
||||||
{
|
|
||||||
if (pthread_cond_timedwait(&m_cv, &m_mutex, &ts) != 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool result = m_signaled.load();
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && result && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&m_mutex);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Reset()
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&m_mutex);
|
|
||||||
m_signaled.store(false);
|
|
||||||
pthread_mutex_unlock(&m_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::WaitForMultiple(Event** events, u32 num_events)
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < num_events; i++)
|
|
||||||
events[i]->Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
Event::Event(bool auto_reset /* = false */) : m_auto_reset(auto_reset) {}
|
|
||||||
|
|
||||||
Event::~Event() = default;
|
|
||||||
|
|
||||||
void Event::Signal()
|
|
||||||
{
|
|
||||||
std::unique_lock lock(m_mutex);
|
|
||||||
m_signaled.store(true);
|
|
||||||
m_cv.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Wait()
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
std::unique_lock lock(m_mutex);
|
|
||||||
m_cv.wait(lock, [this]() { return m_signaled.load(); });
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Event::TryWait(u32 timeout_in_ms)
|
|
||||||
{
|
|
||||||
m_waiters.fetch_add(1);
|
|
||||||
|
|
||||||
std::unique_lock lock(m_mutex);
|
|
||||||
const bool result =
|
|
||||||
m_cv.wait_for(lock, std::chrono::milliseconds(timeout_in_ms), [this]() { return m_signaled.load(); });
|
|
||||||
|
|
||||||
if (m_waiters.fetch_sub(1) == 1 && result && m_auto_reset)
|
|
||||||
m_signaled.store(false);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::Reset()
|
|
||||||
{
|
|
||||||
std::unique_lock lock(m_mutex);
|
|
||||||
m_signaled.store(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Event::WaitForMultiple(Event** events, u32 num_events)
|
|
||||||
{
|
|
||||||
for (u32 i = 0; i < num_events; i++)
|
|
||||||
events[i]->Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace Common
|
|
|
@ -1,57 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
// #define USE_WIN32_EVENT_OBJECTS 1
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(USE_WIN32_EVENT_OBJECTS)
|
|
||||||
#include "windows_headers.h"
|
|
||||||
#include <atomic>
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
|
||||||
#include <atomic>
|
|
||||||
#include <pthread.h>
|
|
||||||
#else
|
|
||||||
#include <atomic>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <mutex>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Common {
|
|
||||||
|
|
||||||
class Event
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Event(bool auto_reset = false);
|
|
||||||
~Event();
|
|
||||||
|
|
||||||
void Reset();
|
|
||||||
void Signal();
|
|
||||||
void Wait();
|
|
||||||
bool TryWait(u32 timeout_in_ms);
|
|
||||||
|
|
||||||
static void WaitForMultiple(Event** events, u32 num_events);
|
|
||||||
|
|
||||||
private:
|
|
||||||
#if defined(_WIN32) && defined(USE_WIN32_EVENT_OBJECTS)
|
|
||||||
void* m_event_handle;
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
CRITICAL_SECTION m_cs;
|
|
||||||
CONDITION_VARIABLE m_cv;
|
|
||||||
std::atomic_uint32_t m_waiters{0};
|
|
||||||
std::atomic_bool m_signaled{false};
|
|
||||||
bool m_auto_reset = false;
|
|
||||||
#elif defined(__linux__) || defined(__APPLE__) || defined(__HAIKU__)
|
|
||||||
pthread_mutex_t m_mutex;
|
|
||||||
pthread_cond_t m_cv;
|
|
||||||
std::atomic_uint32_t m_waiters{0};
|
|
||||||
std::atomic_bool m_signaled{false};
|
|
||||||
bool m_auto_reset = false;
|
|
||||||
#else
|
|
||||||
std::mutex m_mutex;
|
|
||||||
std::condition_variable m_cv;
|
|
||||||
std::atomic_uint32_t m_waiters{0};
|
|
||||||
std::atomic_bool m_signaled{false};
|
|
||||||
bool m_auto_reset = false;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Common
|
|
|
@ -1,5 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "common/event.h"
|
|
||||||
#include "common/heap_array.h"
|
#include "common/heap_array.h"
|
||||||
#include "common/threading.h"
|
#include "common/threading.h"
|
||||||
#include "gpu_types.h"
|
#include "gpu_types.h"
|
||||||
|
|
Loading…
Reference in a new issue