convert locking/cond code to pthreads to get rid of awful c11 api

master
Daniel Kolesa 2016-01-24 15:33:15 +00:00
parent 86170b75c4
commit 4b9faefa5c
1 changed files with 23 additions and 39 deletions

View File

@ -7,53 +7,41 @@
#define OSTD_INTERNAL_MUTEX_HH #define OSTD_INTERNAL_MUTEX_HH
#include <stdlib.h> #include <stdlib.h>
#include <threads.h> #include <pthread.h>
#include "ostd/utility.hh" #include "ostd/utility.hh"
namespace ostd { namespace ostd {
struct Mutex { struct Mutex {
using NativeHandle = mtx_t *; using NativeHandle = pthread_mutex_t *;
Mutex() { constexpr Mutex(): p_mtx(PTHREAD_MUTEX_INITIALIZER) {}
if (mtx_init(&p_mtx, mtx_plain) != thrd_success)
p_mtx = 0;
}
~Mutex() { ~Mutex() {
if (p_mtx) pthread_mutex_destroy(&p_mtx);
mtx_destroy(&p_mtx);
} }
Mutex(const Mutex &) = delete; Mutex(const Mutex &) = delete;
Mutex &operator=(const Mutex &) = delete; Mutex &operator=(const Mutex &) = delete;
bool lock() { bool lock() {
if (!p_mtx) return !pthread_mutex_lock(&p_mtx);
return false;
return mtx_lock(&p_mtx) == thrd_success;
} }
int try_lock() { int try_lock() {
if (!p_mtx) /* TODO handle return value correctly */
return 0; return pthread_mutex_trylock(&p_mtx);
int ret = mtx_trylock(&p_mtx);
if (ret == thrd_busy)
return -1;
return 1;
} }
bool unlock() { bool unlock() {
if (!p_mtx) return !pthread_mutex_unlock(&p_mtx);
return false;
return mtx_unlock(&p_mtx) == thrd_success;
} }
NativeHandle native_handle() { return &p_mtx; } NativeHandle native_handle() { return &p_mtx; }
private: private:
mtx_t p_mtx; pthread_mutex_t p_mtx;
}; };
struct DeferLock {}; struct DeferLock {};
@ -93,12 +81,12 @@ struct UniqueLock {
UniqueLock(MutexType &m, TryToLock): p_mtx(&m) { UniqueLock(MutexType &m, TryToLock): p_mtx(&m) {
int ret = m.try_lock(); int ret = m.try_lock();
if (!ret) { if (ret) {
p_mtx = nullptr; p_mtx = nullptr;
p_owns = false; p_owns = false;
return; return;
} }
p_owns = (ret == 1); p_owns = (ret == 0);
} }
UniqueLock(MutexType &m, AdoptLock): p_mtx(&m), p_owns(true) {} UniqueLock(MutexType &m, AdoptLock): p_mtx(&m), p_owns(true) {}
@ -132,10 +120,10 @@ struct UniqueLock {
} }
int try_lock() { int try_lock() {
if (!p_mtx || p_owns) return 0; if (!p_mtx || p_owns) return 1;
int ret = p_mtx->try_lock(); int ret = p_mtx->try_lock();
if (!ret) return 0; if (ret) return ret;
p_owns = (ret == 1); p_owns = (ret == 0);
return ret; return ret;
} }
@ -168,39 +156,35 @@ private:
}; };
struct Condition { struct Condition {
using NativeHandle = cnd_t *; using NativeHandle = pthread_cond_t *;
Condition() { constexpr Condition(): p_cnd(PTHREAD_COND_INITIALIZER) {}
if (cnd_init(&p_cnd) != thrd_success)
p_cnd = 0;
}
Condition(const Condition &) = delete; Condition(const Condition &) = delete;
Condition &operator=(const Condition &) = delete; Condition &operator=(const Condition &) = delete;
~Condition() { ~Condition() {
if (p_cnd) cnd_destroy(&p_cnd); pthread_cond_destroy(&p_cnd);
} }
bool signal() { bool signal() {
if (!p_cnd) return false; return !pthread_cond_signal(&p_cnd);
return cnd_signal(&p_cnd) == thrd_success;
} }
bool broadcast() { bool broadcast() {
if (!p_cnd) return false; return !pthread_cond_broadcast(&p_cnd);
return cnd_broadcast(&p_cnd) == thrd_success;
} }
bool wait(UniqueLock<Mutex> &l) { bool wait(UniqueLock<Mutex> &l) {
if (!p_cnd) return false; if (!l.owns_lock())
return cnd_wait(&p_cnd, l.mutex()->native_handle()) == thrd_success; return false;
return !pthread_cond_wait(&p_cnd, l.mutex()->native_handle());
} }
NativeHandle native_handle() { return &p_cnd; } NativeHandle native_handle() { return &p_cnd; }
private: private:
cnd_t p_cnd; pthread_cond_t p_cnd;
}; };
} /* namespace ostd */ } /* namespace ostd */