Fix C++11 Windows build of threading code
The initial problem was that mutex_auto_lock.h tries to use std::unique_lock<std::mutex> despite mutex.h not using C++11's std::mutex on Windows. The problem here is the mismatch between C++11 usage conditions of the two headers. This commit moves the decision logic to threads.h and makes sure mutex.h, mutex_auto_lock.h and event.h all use the same features.master
parent
155288ee98
commit
0a16e53b40
|
@ -27,8 +27,8 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
Event::Event()
|
Event::Event()
|
||||||
{
|
{
|
||||||
#if __cplusplus < 201103L
|
#ifndef USE_CPP11_MUTEX
|
||||||
# ifdef _WIN32
|
# if USE_WIN_MUTEX
|
||||||
event = CreateEvent(NULL, false, false, NULL);
|
event = CreateEvent(NULL, false, false, NULL);
|
||||||
# else
|
# else
|
||||||
pthread_cond_init(&cv, NULL);
|
pthread_cond_init(&cv, NULL);
|
||||||
|
@ -38,10 +38,10 @@ Event::Event()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus < 201103L
|
#ifndef USE_CPP11_MUTEX
|
||||||
Event::~Event()
|
Event::~Event()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
CloseHandle(event);
|
CloseHandle(event);
|
||||||
#else
|
#else
|
||||||
pthread_cond_destroy(&cv);
|
pthread_cond_destroy(&cv);
|
||||||
|
@ -53,13 +53,13 @@ Event::~Event()
|
||||||
|
|
||||||
void Event::wait()
|
void Event::wait()
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201103L
|
#if USE_CPP11_MUTEX
|
||||||
MutexAutoLock lock(mutex);
|
MutexAutoLock lock(mutex);
|
||||||
while (!notified) {
|
while (!notified) {
|
||||||
cv.wait(lock);
|
cv.wait(lock);
|
||||||
}
|
}
|
||||||
notified = false;
|
notified = false;
|
||||||
#elif defined(_WIN32)
|
#elif USE_WIN_MUTEX
|
||||||
WaitForSingleObject(event, INFINITE);
|
WaitForSingleObject(event, INFINITE);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
@ -74,11 +74,11 @@ void Event::wait()
|
||||||
|
|
||||||
void Event::signal()
|
void Event::signal()
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201103L
|
#if USE_CPP11_MUTEX
|
||||||
MutexAutoLock lock(mutex);
|
MutexAutoLock lock(mutex);
|
||||||
notified = true;
|
notified = true;
|
||||||
cv.notify_one();
|
cv.notify_one();
|
||||||
#elif defined(_WIN32)
|
#elif USE_WIN_MUTEX
|
||||||
SetEvent(event);
|
SetEvent(event);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
|
|
@ -26,17 +26,12 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#ifndef THREADING_EVENT_H
|
#ifndef THREADING_EVENT_H
|
||||||
#define THREADING_EVENT_H
|
#define THREADING_EVENT_H
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#include "threads.h"
|
||||||
|
|
||||||
|
#if USE_CPP11_MUTEX
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include "threading/mutex.h"
|
#include "threading/mutex.h"
|
||||||
#include "threading/mutex_auto_lock.h"
|
#include "threading/mutex_auto_lock.h"
|
||||||
#elif defined(_WIN32)
|
|
||||||
#ifndef WIN32_LEAN_AND_MEAN
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#endif
|
|
||||||
#include <windows.h>
|
|
||||||
#else
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,18 +44,18 @@ DEALINGS IN THE SOFTWARE.
|
||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
Event();
|
Event();
|
||||||
#if __cplusplus < 201103L
|
#ifndef USE_CPP11_MUTEX
|
||||||
~Event();
|
~Event();
|
||||||
#endif
|
#endif
|
||||||
void wait();
|
void wait();
|
||||||
void signal();
|
void signal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#if __cplusplus >= 201103L
|
#if USE_CPP11_MUTEX
|
||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
bool notified;
|
bool notified;
|
||||||
#elif defined(_WIN32)
|
#elif USE_WIN_MUTEX
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
#else
|
#else
|
||||||
pthread_cond_t cv;
|
pthread_cond_t cv;
|
||||||
|
|
|
@ -23,14 +23,13 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Windows std::mutex is much slower than the critical section API
|
#include "threads.h"
|
||||||
#if __cplusplus < 201103L || defined(_WIN32)
|
|
||||||
|
#ifndef USE_CPP11_MUTEX
|
||||||
|
|
||||||
#include "threading/mutex.h"
|
#include "threading/mutex.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#include <cassert>
|
||||||
#include <cassert>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define UNUSED(expr) do { (void)(expr); } while (0)
|
#define UNUSED(expr) do { (void)(expr); } while (0)
|
||||||
|
|
||||||
|
@ -47,7 +46,7 @@ Mutex::Mutex(bool recursive)
|
||||||
|
|
||||||
void Mutex::init_mutex(bool recursive)
|
void Mutex::init_mutex(bool recursive)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
// Windows critical sections are recursive by default
|
// Windows critical sections are recursive by default
|
||||||
UNUSED(recursive);
|
UNUSED(recursive);
|
||||||
|
|
||||||
|
@ -69,7 +68,7 @@ void Mutex::init_mutex(bool recursive)
|
||||||
|
|
||||||
Mutex::~Mutex()
|
Mutex::~Mutex()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
DeleteCriticalSection(&mutex);
|
DeleteCriticalSection(&mutex);
|
||||||
#else
|
#else
|
||||||
int ret = pthread_mutex_destroy(&mutex);
|
int ret = pthread_mutex_destroy(&mutex);
|
||||||
|
@ -80,7 +79,7 @@ Mutex::~Mutex()
|
||||||
|
|
||||||
void Mutex::lock()
|
void Mutex::lock()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
EnterCriticalSection(&mutex);
|
EnterCriticalSection(&mutex);
|
||||||
#else
|
#else
|
||||||
int ret = pthread_mutex_lock(&mutex);
|
int ret = pthread_mutex_lock(&mutex);
|
||||||
|
@ -91,7 +90,7 @@ void Mutex::lock()
|
||||||
|
|
||||||
void Mutex::unlock()
|
void Mutex::unlock()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
LeaveCriticalSection(&mutex);
|
LeaveCriticalSection(&mutex);
|
||||||
#else
|
#else
|
||||||
int ret = pthread_mutex_unlock(&mutex);
|
int ret = pthread_mutex_unlock(&mutex);
|
||||||
|
@ -104,5 +103,5 @@ RecursiveMutex::RecursiveMutex()
|
||||||
: Mutex(true)
|
: Mutex(true)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#endif
|
#endif // C++11
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,15 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#ifndef THREADING_MUTEX_H
|
#ifndef THREADING_MUTEX_H
|
||||||
#define THREADING_MUTEX_H
|
#define THREADING_MUTEX_H
|
||||||
|
|
||||||
// Windows std::mutex is much slower than the critical section API
|
#include "threads.h"
|
||||||
#if __cplusplus >= 201103L && !defined(_WIN32)
|
|
||||||
|
#if USE_CPP11_MUTEX
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
using Mutex = std::mutex;
|
using Mutex = std::mutex;
|
||||||
using RecursiveMutex = std::recursive_mutex;
|
using RecursiveMutex = std::recursive_mutex;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
#ifndef _WIN32_WINNT
|
#ifndef _WIN32_WINNT
|
||||||
#define _WIN32_WINNT 0x0501
|
#define _WIN32_WINNT 0x0501
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,7 +42,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else // pthread
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -59,9 +60,9 @@ protected:
|
||||||
Mutex(bool recursive);
|
Mutex(bool recursive);
|
||||||
void init_mutex(bool recursive);
|
void init_mutex(bool recursive);
|
||||||
private:
|
private:
|
||||||
#ifdef _WIN32
|
#if USE_WIN_MUTEX
|
||||||
CRITICAL_SECTION mutex;
|
CRITICAL_SECTION mutex;
|
||||||
#else // pthread
|
#else
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -76,6 +77,6 @@ public:
|
||||||
DISABLE_CLASS_COPY(RecursiveMutex);
|
DISABLE_CLASS_COPY(RecursiveMutex);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // C++11
|
#endif // C++11
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -26,7 +26,9 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#ifndef THREADING_MUTEX_AUTO_LOCK_H
|
#ifndef THREADING_MUTEX_AUTO_LOCK_H
|
||||||
#define THREADING_MUTEX_AUTO_LOCK_H
|
#define THREADING_MUTEX_AUTO_LOCK_H
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#include "threads.h"
|
||||||
|
|
||||||
|
#if USE_CPP11_MUTEX
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
using MutexAutoLock = std::unique_lock<std::mutex>;
|
using MutexAutoLock = std::unique_lock<std::mutex>;
|
||||||
using RecursiveMutexAutoLock = std::unique_lock<std::recursive_mutex>;
|
using RecursiveMutexAutoLock = std::unique_lock<std::recursive_mutex>;
|
||||||
|
|
|
@ -198,7 +198,7 @@ bool Thread::kill()
|
||||||
|
|
||||||
m_running = false;
|
m_running = false;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if USE_WIN_THREADS
|
||||||
TerminateThread(m_thread_handle, 0);
|
TerminateThread(m_thread_handle, 0);
|
||||||
CloseHandle(m_thread_handle);
|
CloseHandle(m_thread_handle);
|
||||||
#else
|
#else
|
||||||
|
@ -310,10 +310,16 @@ void Thread::setName(const std::string &name)
|
||||||
|
|
||||||
unsigned int Thread::getNumberOfProcessors()
|
unsigned int Thread::getNumberOfProcessors()
|
||||||
{
|
{
|
||||||
#if __cplusplus >= 201103L
|
#if USE_CPP11_THREADS
|
||||||
|
|
||||||
return std::thread::hardware_concurrency();
|
return std::thread::hardware_concurrency();
|
||||||
|
|
||||||
|
#elif USE_WIN_THREADS
|
||||||
|
|
||||||
|
SYSTEM_INFO sysinfo;
|
||||||
|
GetSystemInfo(&sysinfo);
|
||||||
|
return sysinfo.dwNumberOfProcessors;
|
||||||
|
|
||||||
#elif defined(_SC_NPROCESSORS_ONLN)
|
#elif defined(_SC_NPROCESSORS_ONLN)
|
||||||
|
|
||||||
return sysconf(_SC_NPROCESSORS_ONLN);
|
return sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
@ -335,12 +341,6 @@ unsigned int Thread::getNumberOfProcessors()
|
||||||
|
|
||||||
return get_nprocs();
|
return get_nprocs();
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
|
|
||||||
SYSTEM_INFO sysinfo;
|
|
||||||
GetSystemInfo(&sysinfo);
|
|
||||||
return sysinfo.dwNumberOfProcessors;
|
|
||||||
|
|
||||||
#elif defined(PTW32_VERSION) || defined(__hpux)
|
#elif defined(PTW32_VERSION) || defined(__hpux)
|
||||||
|
|
||||||
return pthread_num_processors_np();
|
return pthread_num_processors_np();
|
||||||
|
@ -359,7 +359,7 @@ bool Thread::bindToProcessor(unsigned int proc_number)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#elif defined(_WIN32)
|
#elif USE_WIN_THREADS
|
||||||
|
|
||||||
return SetThreadAffinityMask(getThreadHandle(), 1 << proc_number);
|
return SetThreadAffinityMask(getThreadHandle(), 1 << proc_number);
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ bool Thread::bindToProcessor(unsigned int proc_number)
|
||||||
|
|
||||||
bool Thread::setPriority(int prio)
|
bool Thread::setPriority(int prio)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if USE_WIN_THREADS
|
||||||
|
|
||||||
return SetThreadPriority(getThreadHandle(), prio);
|
return SetThreadPriority(getThreadHandle(), prio);
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,6 @@ DEALINGS IN THE SOFTWARE.
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#if USE_CPP11_THREADS
|
|
||||||
#include <thread> // for std::thread
|
|
||||||
#endif
|
|
||||||
#ifdef _AIX
|
#ifdef _AIX
|
||||||
#include <sys/thread.h> // for tid_t
|
#include <sys/thread.h> // for tid_t
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,9 +154,11 @@ private:
|
||||||
Atomic<bool> m_running;
|
Atomic<bool> m_running;
|
||||||
Mutex m_mutex;
|
Mutex m_mutex;
|
||||||
|
|
||||||
#ifndef USE_CPP11_THREADS
|
#if USE_CPP11_THREADS
|
||||||
|
std::thread *m_thread_obj;
|
||||||
|
#else
|
||||||
threadhandle_t m_thread_handle;
|
threadhandle_t m_thread_handle;
|
||||||
# if _WIN32
|
# if USE_WIN_THREADS
|
||||||
threadid_t m_thread_id;
|
threadid_t m_thread_id;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,10 +171,6 @@ private:
|
||||||
tid_t m_kernel_thread_id;
|
tid_t m_kernel_thread_id;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if USE_CPP11_THREADS
|
|
||||||
std::thread *m_thread_obj;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DISABLE_CLASS_COPY(Thread);
|
DISABLE_CLASS_COPY(Thread);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define THREADS_HEADER
|
#define THREADS_HEADER
|
||||||
|
|
||||||
//
|
//
|
||||||
// Determine which threading API we will use
|
// Determine which threading APIs we will use
|
||||||
//
|
//
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
#define USE_CPP11_THREADS 1
|
#define USE_CPP11_THREADS 1
|
||||||
|
@ -31,11 +31,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#define USE_POSIX_THREADS 1
|
#define USE_POSIX_THREADS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// Prefer critical section API because std::mutex is much slower on Windows
|
||||||
|
#define USE_WIN_MUTEX 1
|
||||||
|
#elif __cplusplus >= 201103L
|
||||||
|
#define USE_CPP11_MUTEX 1
|
||||||
|
#else
|
||||||
|
#define USE_POSIX_MUTEX 1
|
||||||
|
#endif
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
|
||||||
|
|
||||||
#if USE_CPP11_THREADS
|
#if USE_CPP11_THREADS
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#elif USE_POSIX_THREADS
|
||||||
|
#include <pthread.h>
|
||||||
|
#else
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "threading/mutex.h"
|
#include "threading/mutex.h"
|
||||||
|
|
Loading…
Reference in New Issue