summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2013-03-29 07:42:41 -0700
committerPierre Bourdon <delroth@gmail.com>2013-03-29 07:42:41 -0700
commita8513e46050fe0ae47ff543ec84c2f022e439f6a (patch)
tree35d2e25be152dde9e1730940b14520d593e38604 /Source/Core
parent4895e38bd59372e9813bb1b10f36ed49a438808f (diff)
Re-add StdConditionVariable, MSVC 2010 does not support <condition_variable>
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Common.vcxproj1
-rw-r--r--Source/Core/Common/Common.vcxproj.filters1
-rw-r--r--Source/Core/Common/Src/StdConditionVariable.h166
-rw-r--r--Source/Core/Common/Src/Thread.h2
4 files changed, 169 insertions, 1 deletions
diff --git a/Source/Core/Common/Common.vcxproj b/Source/Core/Common/Common.vcxproj
index 12370296b9..e8e45187b7 100644
--- a/Source/Core/Common/Common.vcxproj
+++ b/Source/Core/Common/Common.vcxproj
@@ -241,6 +241,7 @@
<ClInclude Include="Src\SDCardUtil.h" />
<ClInclude Include="Src\Setup.h" />
<ClInclude Include="Src\stdafx.h" />
+ <ClInclude Include="Src\StdConditionVariable.h" />
<ClInclude Include="Src\StringUtil.h" />
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
diff --git a/Source/Core/Common/Common.vcxproj.filters b/Source/Core/Common/Common.vcxproj.filters
index f8915af9a2..878ead5d27 100644
--- a/Source/Core/Common/Common.vcxproj.filters
+++ b/Source/Core/Common/Common.vcxproj.filters
@@ -85,6 +85,7 @@
<ClInclude Include="Src\SDCardUtil.h" />
<ClInclude Include="Src\Setup.h" />
<ClInclude Include="Src\stdafx.h" />
+ <ClInclude Include="Src\StdConditionVariable.h" />
<ClInclude Include="Src\StringUtil.h" />
<ClInclude Include="Src\SymbolDB.h" />
<ClInclude Include="Src\SysConf.h" />
diff --git a/Source/Core/Common/Src/StdConditionVariable.h b/Source/Core/Common/Src/StdConditionVariable.h
new file mode 100644
index 0000000000..9a045a650b
--- /dev/null
+++ b/Source/Core/Common/Src/StdConditionVariable.h
@@ -0,0 +1,166 @@
+
+#ifndef CONDITION_VARIABLE_H_
+#define CONDITION_VARIABLE_H_
+
+#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
+#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+
+#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID
+
+// GCC 4.4 provides <condition_variable>
+#include <condition_variable>
+
+#elif defined(__has_include) && __has_include(<condition_variable>)
+
+// clang and libc++ provide <condition_variable> on OSX. However, the version
+// of libc++ bundled with OSX 10.7 and 10.8 is buggy: it uses _ as a variable.
+//
+// We work around this issue by undefining and redefining _.
+
+#undef _
+#include <condition_variable>
+#define _(s) wxGetTranslation((s))
+
+#else
+
+// partial std::condition_variable implementation for win32/pthread
+
+#include <mutex>
+
+#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
+#define USE_RVALUE_REFERENCES
+#endif
+
+#if defined(_WIN32) && defined(_M_X64)
+#define USE_CONDITION_VARIABLES
+#elif defined(_WIN32)
+#define USE_EVENTS
+#endif
+
+namespace std
+{
+
+class condition_variable
+{
+#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
+ typedef CONDITION_VARIABLE native_type;
+#elif defined(_WIN32)
+ typedef HANDLE native_type;
+#else
+ typedef pthread_cond_t native_type;
+#endif
+
+public:
+
+#ifdef USE_EVENTS
+ typedef native_type native_handle_type;
+#else
+ typedef native_type* native_handle_type;
+#endif
+
+ condition_variable()
+ {
+#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
+ InitializeConditionVariable(&m_handle);
+#elif defined(_WIN32)
+ m_handle = CreateEvent(NULL, false, false, NULL);
+#else
+ pthread_cond_init(&m_handle, NULL);
+#endif
+ }
+
+ ~condition_variable()
+ {
+#if defined(_WIN32) && !defined(USE_CONDITION_VARIABLES)
+ CloseHandle(m_handle);
+#elif !defined(_WIN32)
+ pthread_cond_destroy(&m_handle);
+#endif
+ }
+
+ condition_variable(const condition_variable&) /*= delete*/;
+ condition_variable& operator=(const condition_variable&) /*= delete*/;
+
+ void notify_one()
+ {
+#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
+ WakeConditionVariable(&m_handle);
+#elif defined(_WIN32)
+ SetEvent(m_handle);
+#else
+ pthread_cond_signal(&m_handle);
+#endif
+ }
+
+ void notify_all()
+ {
+#if defined(_WIN32) && defined(USE_CONDITION_VARIABLES)
+ WakeAllConditionVariable(&m_handle);
+#elif defined(_WIN32)
+ // TODO: broken
+ SetEvent(m_handle);
+#else
+ pthread_cond_broadcast(&m_handle);
+#endif
+ }
+
+ void wait(unique_lock<mutex>& lock)
+ {
+#ifdef _WIN32
+ #ifdef USE_SRWLOCKS
+ SleepConditionVariableSRW(&m_handle, lock.mutex()->native_handle(), INFINITE, 0);
+ #elif defined(USE_CONDITION_VARIABLES)
+ SleepConditionVariableCS(&m_handle, lock.mutex()->native_handle(), INFINITE);
+ #else
+ // TODO: broken, the unlock and wait need to be atomic
+ lock.unlock();
+ WaitForSingleObject(m_handle, INFINITE);
+ lock.lock();
+ #endif
+#else
+ pthread_cond_wait(&m_handle, lock.mutex()->native_handle());
+#endif
+ }
+
+ template <class Predicate>
+ void wait(unique_lock<mutex>& lock, Predicate pred)
+ {
+ while (!pred())
+ wait(lock);
+ }
+
+ //template <class Clock, class Duration>
+ //cv_status wait_until(unique_lock<mutex>& lock,
+ // const chrono::time_point<Clock, Duration>& abs_time);
+
+ //template <class Clock, class Duration, class Predicate>
+ // bool wait_until(unique_lock<mutex>& lock,
+ // const chrono::time_point<Clock, Duration>& abs_time,
+ // Predicate pred);
+
+ //template <class Rep, class Period>
+ //cv_status wait_for(unique_lock<mutex>& lock,
+ // const chrono::duration<Rep, Period>& rel_time);
+
+ //template <class Rep, class Period, class Predicate>
+ // bool wait_for(unique_lock<mutex>& lock,
+ // const chrono::duration<Rep, Period>& rel_time,
+ // Predicate pred);
+
+ native_handle_type native_handle()
+ {
+#ifdef USE_EVENTS
+ return m_handle;
+#else
+ return &m_handle;
+#endif
+ }
+
+private:
+ native_type m_handle;
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h
index 5ced2b2b3e..1eb671f223 100644
--- a/Source/Core/Common/Src/Thread.h
+++ b/Source/Core/Common/Src/Thread.h
@@ -22,7 +22,7 @@
// This conflicts with gettext's use of _ as a macro.
#undef _
-#include <condition_variable>
+#include "StdConditionVariable.h"
#include <mutex>
#include <thread>