summaryrefslogtreecommitdiff
path: root/plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc')
-rw-r--r--plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc995
1 files changed, 0 insertions, 995 deletions
diff --git a/plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc b/plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc
deleted file mode 100644
index e67a6ae4c4..0000000000
--- a/plugins/Dbx_kyoto/src/kyotocabinet/kcthread.cc
+++ /dev/null
@@ -1,995 +0,0 @@
-/*************************************************************************************************
- * Threading devices
- * Copyright (C) 2009-2012 FAL Labs
- * This file is part of Kyoto Cabinet.
- * This program is free software: you can redistribute it and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation, either version
- * 3 of the License, or any later version.
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License along with this program.
- * If not, see <http://www.gnu.org/licenses/>.
- *************************************************************************************************/
-
-
-#include "kcthread.h"
-#include "myconf.h"
-
-namespace kyotocabinet { // common namespace
-
-
-/**
- * Constants for implementation.
- */
-namespace {
-const uint32_t LOCKBUSYLOOP = 8192; ///< threshold of busy loop and sleep for locking
-const size_t LOCKSEMNUM = 256; ///< number of semaphores for locking
-}
-
-
-/**
- * Thread internal.
- */
-struct ThreadCore {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- ::HANDLE th; ///< handle
-#else
- ::pthread_t th; ///< identifier
- bool alive; ///< alive flag
-#endif
-};
-
-
-/**
- * CondVar internal.
- */
-struct CondVarCore {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- ::CRITICAL_SECTION mutex; ///< mutex
- uint32_t wait; ///< wait count
- uint32_t wake; ///< wake count
- ::HANDLE sev; ///< signal event handle
- ::HANDLE fev; ///< finish event handle
-#else
- ::pthread_cond_t cond; ///< condition
-#endif
-};
-
-
-/**
- * Call the running thread.
- * @param arg the thread.
- * @return always NULL.
- */
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
-static ::DWORD threadrun(::LPVOID arg);
-#else
-static void* threadrun(void* arg);
-#endif
-
-
-/**
- * Default constructor.
- */
-Thread::Thread() : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ThreadCore* core = new ThreadCore;
- core->th = NULL;
- opq_ = (void*)core;
-#else
- _assert_(true);
- ThreadCore* core = new ThreadCore;
- core->alive = false;
- opq_ = (void*)core;
-#endif
-}
-
-
-/**
- * Destructor.
- */
-Thread::~Thread() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (core->th) join();
- delete core;
-#else
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (core->alive) join();
- delete core;
-#endif
-}
-
-
-/**
- * Start the thread.
- */
-void Thread::start() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (core->th) throw std::invalid_argument("already started");
- ::DWORD id;
- core->th = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadrun, this, 0, &id);
- if (!core->th) throw std::runtime_error("CreateThread");
-#else
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (core->alive) throw std::invalid_argument("already started");
- if (::pthread_create(&core->th, NULL, threadrun, this) != 0)
- throw std::runtime_error("pthread_create");
- core->alive = true;
-#endif
-}
-
-
-/**
- * Wait for the thread to finish.
- */
-void Thread::join() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (!core->th) throw std::invalid_argument("not alive");
- if (::WaitForSingleObject(core->th, INFINITE) == WAIT_FAILED)
- throw std::runtime_error("WaitForSingleObject");
- ::CloseHandle(core->th);
- core->th = NULL;
-#else
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (!core->alive) throw std::invalid_argument("not alive");
- core->alive = false;
- if (::pthread_join(core->th, NULL) != 0) throw std::runtime_error("pthread_join");
-#endif
-}
-
-
-/**
- * Put the thread in the detached state.
- */
-void Thread::detach() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
-#else
- _assert_(true);
- ThreadCore* core = (ThreadCore*)opq_;
- if (!core->alive) throw std::invalid_argument("not alive");
- core->alive = false;
- if (::pthread_detach(core->th) != 0) throw std::runtime_error("pthread_detach");
-#endif
-}
-
-
-/**
- * Terminate the running thread.
- */
-void Thread::exit() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::ExitThread(0);
-#else
- _assert_(true);
- ::pthread_exit(NULL);
-#endif
-}
-
-
-/**
- * Yield the processor from the current thread.
- */
-void Thread::yield() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::Sleep(0);
-#else
- _assert_(true);
- ::sched_yield();
-#endif
-}
-
-
-/**
- * Chill the processor by suspending execution for a quick moment.
- */
-void Thread::chill() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::Sleep(21);
-#else
- _assert_(true);
- struct ::timespec req;
- req.tv_sec = 0;
- req.tv_nsec = 21 * 1000 * 1000;
- ::nanosleep(&req, NULL);
-#endif
-}
-
-
-
-/**
- * Suspend execution of the current thread.
- */
-bool Thread::sleep(double sec) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(sec >= 0.0);
- if (sec <= 0.0) {
- yield();
- return true;
- }
- if (sec > INT32MAX) sec = INT32MAX;
- ::Sleep(sec * 1000);
- return true;
-#else
- _assert_(sec >= 0.0);
- if (sec <= 0.0) {
- yield();
- return true;
- }
- if (sec > INT32MAX) sec = INT32MAX;
- double integ, fract;
- fract = std::modf(sec, &integ);
- struct ::timespec req, rem;
- req.tv_sec = (time_t)integ;
- req.tv_nsec = (long)(fract * 999999000);
- while (::nanosleep(&req, &rem) != 0) {
- if (errno != EINTR) return false;
- req = rem;
- }
- return true;
-#endif
-}
-
-
-/**
- * Get the hash value of the current thread.
- */
-int64_t Thread::hash() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- return ::GetCurrentThreadId();
-#else
- _assert_(true);
- pthread_t tid = pthread_self();
- int64_t num;
- if (sizeof(tid) == sizeof(num)) {
- std::memcpy(&num, &tid, sizeof(num));
- } else if (sizeof(tid) == sizeof(int32_t)) {
- uint32_t inum;
- std::memcpy(&inum, &tid, sizeof(inum));
- num = inum;
- } else {
- num = hashmurmur(&tid, sizeof(tid));
- }
- return num & INT64MAX;
-#endif
-}
-
-
-/**
- * Call the running thread.
- */
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
-static ::DWORD threadrun(::LPVOID arg) {
- _assert_(true);
- Thread* thread = (Thread*)arg;
- thread->run();
- return NULL;
-}
-#else
-static void* threadrun(void* arg) {
- _assert_(true);
- Thread* thread = (Thread*)arg;
- thread->run();
- return NULL;
-}
-#endif
-
-
-/**
- * Default constructor.
- */
-Mutex::Mutex() : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = new ::CRITICAL_SECTION;
- ::InitializeCriticalSection(mutex);
- opq_ = (void*)mutex;
-#else
- _assert_(true);
- ::pthread_mutex_t* mutex = new ::pthread_mutex_t;
- if (::pthread_mutex_init(mutex, NULL) != 0) throw std::runtime_error("pthread_mutex_init");
- opq_ = (void*)mutex;
-#endif
-}
-
-
-/**
- * Constructor with the specifications.
- */
-Mutex::Mutex(Type type) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = new ::CRITICAL_SECTION;
- ::InitializeCriticalSection(mutex);
- opq_ = (void*)mutex;
-#else
- _assert_(true);
- ::pthread_mutexattr_t attr;
- if (::pthread_mutexattr_init(&attr) != 0) throw std::runtime_error("pthread_mutexattr_init");
- switch (type) {
- case FAST: {
- break;
- }
- case ERRORCHECK: {
- if (::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
- throw std::runtime_error("pthread_mutexattr_settype");
- break;
- }
- case RECURSIVE: {
- if (::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
- throw std::runtime_error("pthread_mutexattr_settype");
- break;
- }
- }
- ::pthread_mutex_t* mutex = new ::pthread_mutex_t;
- if (::pthread_mutex_init(mutex, &attr) != 0) throw std::runtime_error("pthread_mutex_init");
- ::pthread_mutexattr_destroy(&attr);
- opq_ = (void*)mutex;
-#endif
-}
-
-
-/**
- * Destructor.
- */
-Mutex::~Mutex() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = (::CRITICAL_SECTION*)opq_;
- ::DeleteCriticalSection(mutex);
- delete mutex;
-#else
- _assert_(true);
- ::pthread_mutex_t* mutex = (::pthread_mutex_t*)opq_;
- ::pthread_mutex_destroy(mutex);
- delete mutex;
-#endif
-}
-
-
-/**
- * Get the lock.
- */
-void Mutex::lock() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = (::CRITICAL_SECTION*)opq_;
- ::EnterCriticalSection(mutex);
-#else
- _assert_(true);
- ::pthread_mutex_t* mutex = (::pthread_mutex_t*)opq_;
- if (::pthread_mutex_lock(mutex) != 0) throw std::runtime_error("pthread_mutex_lock");
-#endif
-}
-
-
-/**
- * Try to get the lock.
- */
-bool Mutex::lock_try() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = (::CRITICAL_SECTION*)opq_;
- if (!::TryEnterCriticalSection(mutex)) return false;
- return true;
-#else
- _assert_(true);
- ::pthread_mutex_t* mutex = (::pthread_mutex_t*)opq_;
- int32_t ecode = ::pthread_mutex_trylock(mutex);
- if (ecode == 0) return true;
- if (ecode != EBUSY) throw std::runtime_error("pthread_mutex_trylock");
- return false;
-#endif
-}
-
-
-/**
- * Try to get the lock.
- */
-bool Mutex::lock_try(double sec) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_) || defined(_SYS_CYGWIN_) || defined(_SYS_MACOSX_)
- _assert_(sec >= 0.0);
- if (lock_try()) return true;
- double end = time() + sec;
- Thread::yield();
- uint32_t wcnt = 0;
- while (!lock_try()) {
- if (time() > end) return false;
- if (wcnt >= LOCKBUSYLOOP) {
- Thread::chill();
- } else {
- Thread::yield();
- wcnt++;
- }
- }
- return true;
-#else
- _assert_(sec >= 0.0);
- ::pthread_mutex_t* mutex = (::pthread_mutex_t*)opq_;
- struct ::timeval tv;
- struct ::timespec ts;
- if (::gettimeofday(&tv, NULL) == 0) {
- double integ;
- double fract = std::modf(sec, &integ);
- ts.tv_sec = tv.tv_sec + (time_t)integ;
- ts.tv_nsec = (long)(tv.tv_usec * 1000.0 + fract * 999999000);
- if (ts.tv_nsec >= 1000000000) {
- ts.tv_nsec -= 1000000000;
- ts.tv_sec++;
- }
- } else {
- ts.tv_sec = std::time(NULL) + 1;
- ts.tv_nsec = 0;
- }
- int32_t ecode = ::pthread_mutex_timedlock(mutex, &ts);
- if (ecode == 0) return true;
- if (ecode != ETIMEDOUT) throw std::runtime_error("pthread_mutex_timedlock");
- return false;
-#endif
-}
-
-
-/**
- * Release the lock.
- */
-void Mutex::unlock() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::CRITICAL_SECTION* mutex = (::CRITICAL_SECTION*)opq_;
- ::LeaveCriticalSection(mutex);
-#else
- _assert_(true);
- ::pthread_mutex_t* mutex = (::pthread_mutex_t*)opq_;
- if (::pthread_mutex_unlock(mutex) != 0) throw std::runtime_error("pthread_mutex_unlock");
-#endif
-}
-
-
-/**
- * SlottedMutex internal.
- */
-struct SlottedMutexCore {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- ::CRITICAL_SECTION* mutexes; ///< primitives
- size_t slotnum; ///< number of slots
-#else
- ::pthread_mutex_t* mutexes; ///< primitives
- size_t slotnum; ///< number of slots
-#endif
-};
-
-
-/**
- * Constructor.
- */
-SlottedMutex::SlottedMutex(size_t slotnum) : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = new SlottedMutexCore;
- ::CRITICAL_SECTION* mutexes = new ::CRITICAL_SECTION[slotnum];
- for (size_t i = 0; i < slotnum; i++) {
- ::InitializeCriticalSection(mutexes + i);
- }
- core->mutexes = mutexes;
- core->slotnum = slotnum;
- opq_ = (void*)core;
-#else
- _assert_(true);
- SlottedMutexCore* core = new SlottedMutexCore;
- ::pthread_mutex_t* mutexes = new ::pthread_mutex_t[slotnum];
- for (size_t i = 0; i < slotnum; i++) {
- if (::pthread_mutex_init(mutexes + i, NULL) != 0)
- throw std::runtime_error("pthread_mutex_init");
- }
- core->mutexes = mutexes;
- core->slotnum = slotnum;
- opq_ = (void*)core;
-#endif
-}
-
-
-/**
- * Destructor.
- */
-SlottedMutex::~SlottedMutex() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::CRITICAL_SECTION* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- ::DeleteCriticalSection(mutexes + i);
- }
- delete[] mutexes;
- delete core;
-#else
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::pthread_mutex_t* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- ::pthread_mutex_destroy(mutexes + i);
- }
- delete[] mutexes;
- delete core;
-#endif
-}
-
-
-/**
- * Get the lock of a slot.
- */
-void SlottedMutex::lock(size_t idx) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::EnterCriticalSection(core->mutexes + idx);
-#else
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- if (::pthread_mutex_lock(core->mutexes + idx) != 0)
- throw std::runtime_error("pthread_mutex_lock");
-#endif
-}
-
-
-/**
- * Release the lock of a slot.
- */
-void SlottedMutex::unlock(size_t idx) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::LeaveCriticalSection(core->mutexes + idx);
-#else
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- if (::pthread_mutex_unlock(core->mutexes + idx) != 0)
- throw std::runtime_error("pthread_mutex_unlock");
-#endif
-}
-
-
-/**
- * Get the locks of all slots.
- */
-void SlottedMutex::lock_all() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::CRITICAL_SECTION* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- ::EnterCriticalSection(mutexes + i);
- }
-#else
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::pthread_mutex_t* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- if (::pthread_mutex_lock(mutexes + i) != 0)
- throw std::runtime_error("pthread_mutex_lock");
- }
-#endif
-}
-
-
-/**
- * Release the locks of all slots.
- */
-void SlottedMutex::unlock_all() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::CRITICAL_SECTION* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- ::LeaveCriticalSection(mutexes + i);
- }
-#else
- _assert_(true);
- SlottedMutexCore* core = (SlottedMutexCore*)opq_;
- ::pthread_mutex_t* mutexes = core->mutexes;
- size_t slotnum = core->slotnum;
- for (size_t i = 0; i < slotnum; i++) {
- if (::pthread_mutex_unlock(mutexes + i) != 0)
- throw std::runtime_error("pthread_mutex_unlock");
- }
-#endif
-}
-
-
-
-
-/**
- * Default constructor.
- */
-CondVar::CondVar() : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- CondVarCore* core = new CondVarCore;
- ::InitializeCriticalSection(&core->mutex);
- core->wait = 0;
- core->wake = 0;
- core->sev = ::CreateEvent(NULL, true, false, NULL);
- if (!core->sev) throw std::runtime_error("CreateEvent");
- core->fev = ::CreateEvent(NULL, false, false, NULL);
- if (!core->fev) throw std::runtime_error("CreateEvent");
- opq_ = (void*)core;
-#else
- _assert_(true);
- CondVarCore* core = new CondVarCore;
- if (::pthread_cond_init(&core->cond, NULL) != 0)
- throw std::runtime_error("pthread_cond_init");
- opq_ = (void*)core;
-#endif
-}
-
-
-/**
- * Destructor.
- */
-CondVar::~CondVar() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- ::CloseHandle(core->fev);
- ::CloseHandle(core->sev);
- ::DeleteCriticalSection(&core->mutex);
-#else
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- ::pthread_cond_destroy(&core->cond);
- delete core;
-#endif
-}
-
-
-/**
- * Wait for the signal.
- */
-void CondVar::wait(Mutex* mutex) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(mutex);
- CondVarCore* core = (CondVarCore*)opq_;
- ::CRITICAL_SECTION* mymutex = (::CRITICAL_SECTION*)mutex->opq_;
- ::EnterCriticalSection(&core->mutex);
- core->wait++;
- ::LeaveCriticalSection(&core->mutex);
- ::LeaveCriticalSection(mymutex);
- while (true) {
- ::WaitForSingleObject(core->sev, INFINITE);
- ::EnterCriticalSection(&core->mutex);
- if (core->wake > 0) {
- core->wait--;
- core->wake--;
- if (core->wake < 1) {
- ::ResetEvent(core->sev);
- ::SetEvent(core->fev);
- }
- ::LeaveCriticalSection(&core->mutex);
- break;
- }
- ::LeaveCriticalSection(&core->mutex);
- }
- ::EnterCriticalSection(mymutex);
-#else
- _assert_(mutex);
- CondVarCore* core = (CondVarCore*)opq_;
- ::pthread_mutex_t* mymutex = (::pthread_mutex_t*)mutex->opq_;
- if (::pthread_cond_wait(&core->cond, mymutex) != 0)
- throw std::runtime_error("pthread_cond_wait");
-#endif
-}
-
-
-/**
- * Wait for the signal.
- */
-bool CondVar::wait(Mutex* mutex, double sec) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(mutex && sec >= 0);
- if (sec <= 0) return false;
- CondVarCore* core = (CondVarCore*)opq_;
- ::CRITICAL_SECTION* mymutex = (::CRITICAL_SECTION*)mutex->opq_;
- ::EnterCriticalSection(&core->mutex);
- core->wait++;
- ::LeaveCriticalSection(&core->mutex);
- ::LeaveCriticalSection(mymutex);
- while (true) {
- if (::WaitForSingleObject(core->sev, sec * 1000) == WAIT_TIMEOUT) {
- ::EnterCriticalSection(&core->mutex);
- if (::WaitForSingleObject(core->sev, 0) == WAIT_TIMEOUT) {
- core->wait--;
- ::SetEvent(core->fev);
- ::LeaveCriticalSection(&core->mutex);
- ::EnterCriticalSection(mymutex);
- return false;
- }
- ::LeaveCriticalSection(&core->mutex);
- }
- ::EnterCriticalSection(&core->mutex);
- if (core->wake > 0) {
- core->wait--;
- core->wake--;
- if (core->wake < 1) {
- ::ResetEvent(core->sev);
- ::SetEvent(core->fev);
- }
- ::LeaveCriticalSection(&core->mutex);
- break;
- }
- ::LeaveCriticalSection(&core->mutex);
- }
- ::EnterCriticalSection(mymutex);
- return true;
-#else
- _assert_(mutex && sec >= 0);
- if (sec <= 0) return false;
- CondVarCore* core = (CondVarCore*)opq_;
- ::pthread_mutex_t* mymutex = (::pthread_mutex_t*)mutex->opq_;
- struct ::timeval tv;
- struct ::timespec ts;
- if (::gettimeofday(&tv, NULL) == 0) {
- double integ;
- double fract = std::modf(sec, &integ);
- ts.tv_sec = tv.tv_sec + (time_t)integ;
- ts.tv_nsec = (long)(tv.tv_usec * 1000.0 + fract * 999999000);
- if (ts.tv_nsec >= 1000000000) {
- ts.tv_nsec -= 1000000000;
- ts.tv_sec++;
- }
- } else {
- ts.tv_sec = std::time(NULL) + 1;
- ts.tv_nsec = 0;
- }
- int32_t ecode = ::pthread_cond_timedwait(&core->cond, mymutex, &ts);
- if (ecode == 0) return true;
- if (ecode != ETIMEDOUT && ecode != EINTR)
- throw std::runtime_error("pthread_cond_timedwait");
- return false;
-#endif
-}
-
-
-/**
- * Send the wake-up signal to another waiting thread.
- */
-void CondVar::signal() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- ::EnterCriticalSection(&core->mutex);
- if (core->wait > 0) {
- core->wake = 1;
- ::SetEvent(core->sev);
- ::LeaveCriticalSection(&core->mutex);
- ::WaitForSingleObject(core->fev, INFINITE);
- } else {
- ::LeaveCriticalSection(&core->mutex);
- }
-#else
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- if (::pthread_cond_signal(&core->cond) != 0)
- throw std::runtime_error("pthread_cond_signal");
-#endif
-}
-
-
-/**
- * Send the wake-up signals to all waiting threads.
- */
-void CondVar::broadcast() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- ::EnterCriticalSection(&core->mutex);
- if (core->wait > 0) {
- core->wake = core->wait;
- ::SetEvent(core->sev);
- ::LeaveCriticalSection(&core->mutex);
- ::WaitForSingleObject(core->fev, INFINITE);
- } else {
- ::LeaveCriticalSection(&core->mutex);
- }
-#else
- _assert_(true);
- CondVarCore* core = (CondVarCore*)opq_;
- if (::pthread_cond_broadcast(&core->cond) != 0)
- throw std::runtime_error("pthread_cond_broadcast");
-#endif
-}
-
-
-/**
- * Default constructor.
- */
-TSDKey::TSDKey() : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::DWORD key = ::TlsAlloc();
- if (key == 0xFFFFFFFF) throw std::runtime_error("TlsAlloc");
- opq_ = (void*)key;
-#else
- _assert_(true);
- ::pthread_key_t* key = new ::pthread_key_t;
- if (::pthread_key_create(key, NULL) != 0)
- throw std::runtime_error("pthread_key_create");
- opq_ = (void*)key;
-#endif
-}
-
-
-/**
- * Constructor with the specifications.
- */
-TSDKey::TSDKey(void (*dstr)(void*)) : opq_(NULL) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::DWORD key = ::TlsAlloc();
- if (key == 0xFFFFFFFF) throw std::runtime_error("TlsAlloc");
- opq_ = (void*)key;
-#else
- _assert_(true);
- ::pthread_key_t* key = new ::pthread_key_t;
- if (::pthread_key_create(key, dstr) != 0)
- throw std::runtime_error("pthread_key_create");
- opq_ = (void*)key;
-#endif
-}
-
-
-/**
- * Destructor.
- */
-TSDKey::~TSDKey() {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::DWORD key = (::DWORD)opq_;
- ::TlsFree(key);
-#else
- _assert_(true);
- ::pthread_key_t* key = (::pthread_key_t*)opq_;
- ::pthread_key_delete(*key);
- delete key;
-#endif
-}
-
-
-/**
- * Set the value.
- */
-void TSDKey::set(void* ptr) {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::DWORD key = (::DWORD)opq_;
- if (!::TlsSetValue(key, ptr)) std::runtime_error("TlsSetValue");
-#else
- _assert_(true);
- ::pthread_key_t* key = (::pthread_key_t*)opq_;
- if (::pthread_setspecific(*key, ptr) != 0)
- throw std::runtime_error("pthread_setspecific");
-#endif
-}
-
-
-/**
- * Get the value.
- */
-void* TSDKey::get() const {
-#if defined(_SYS_MSVC_) || defined(_SYS_MINGW_)
- _assert_(true);
- ::DWORD key = (::DWORD)opq_;
- return ::TlsGetValue(key);
-#else
- _assert_(true);
- ::pthread_key_t* key = (::pthread_key_t*)opq_;
- return ::pthread_getspecific(*key);
-#endif
-}
-
-
-/**
- * Set the new value.
- */
-int64_t AtomicInt64::set(int64_t val) {
-#if (defined(_SYS_MSVC_) || defined(_SYS_MINGW_)) && defined(_SYS_WIN64_)
- _assert_(true);
- return ::InterlockedExchange((uint64_t*)&value_, val);
-#elif _KC_GCCATOMIC
- _assert_(true);
- int64_t oval = __sync_lock_test_and_set(&value_, val);
- __sync_synchronize();
- return oval;
-#else
- _assert_(true);
- int64_t oval = value_;
- value_ = val;
- return oval;
-#endif
-}
-
-
-/**
- * Add a value.
- */
-int64_t AtomicInt64::add(int64_t val) {
-#if (defined(_SYS_MSVC_) || defined(_SYS_MINGW_)) && defined(_SYS_WIN64_)
- _assert_(true);
- return ::InterlockedExchangeAdd((uint64_t*)&value_, val);
-#elif _KC_GCCATOMIC
- _assert_(true);
- int64_t oval = __sync_fetch_and_add(&value_, val);
- __sync_synchronize();
- return oval;
-#else
- _assert_(true);
- int64_t oval = value_;
- value_ += val;
- return oval;
-#endif
-}
-
-
-/**
- * Perform compare-and-swap.
- */
-bool AtomicInt64::cas(int64_t oval, int64_t nval) {
-#if (defined(_SYS_MSVC_) || defined(_SYS_MINGW_)) && defined(_SYS_WIN64_)
- _assert_(true);
- return ::InterlockedCompareExchange((uint64_t*)&value_, nval, oval) == oval;
-#elif _KC_GCCATOMIC
- _assert_(true);
- bool rv = __sync_bool_compare_and_swap(&value_, oval, nval);
- __sync_synchronize();
- return rv;
-#else
- _assert_(true);
- bool rv = false;
- if (value_ == oval) {
- value_ = nval;
- rv = true;
- }
- return rv;
-#endif
-}
-
-
-/**
- * Get the current value.
- */
-int64_t AtomicInt64::get() const {
-#if (defined(_SYS_MSVC_) || defined(_SYS_MINGW_)) && defined(_SYS_WIN64_)
- _assert_(true);
- return ::InterlockedExchangeAdd((uint64_t*)&value_, 0);
-#elif _KC_GCCATOMIC
- _assert_(true);
- return __sync_fetch_and_add((int64_t*)&value_, 0);
-#else
- _assert_(true);
- int64_t oval = value_;
- return oval;
-#endif
-}
-
-
-} // common namespace
-
-// END OF FILE