summaryrefslogtreecommitdiffstats
path: root/src/uscxml/concurrency/tinythread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/concurrency/tinythread.cpp')
-rw-r--r--src/uscxml/concurrency/tinythread.cpp335
1 files changed, 0 insertions, 335 deletions
diff --git a/src/uscxml/concurrency/tinythread.cpp b/src/uscxml/concurrency/tinythread.cpp
deleted file mode 100644
index d46cda3..0000000
--- a/src/uscxml/concurrency/tinythread.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
-Copyright (c) 2010-2012 Marcus Geelnard
-
-This software is provided 'as-is', without any express or implied
-warranty. In no event will the authors be held liable for any damages
-arising from the use of this software.
-
-Permission is granted to anyone to use this software for any purpose,
-including commercial applications, and to alter it and redistribute it
-freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
-
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software. This version was altered!
-
- 3. This notice may not be removed or altered from any source
- distribution.
-*/
-
-#include <exception>
-#include "tinythread.h"
-
-#if defined(_TTHREAD_POSIX_)
-#include <unistd.h>
-#include <map>
-#elif defined(_TTHREAD_WIN32_)
-#include <process.h>
-#endif
-
-namespace tthread {
-
-unsigned long long int timeStamp() {
- unsigned long long int time = 0;
-#ifdef WIN32
- FILETIME tv;
- GetSystemTimeAsFileTime(&tv);
- time = (((unsigned long long int) tv.dwHighDateTime) << 32) + tv.dwLowDateTime;
- time /= 10000;
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- time += tv.tv_sec * 1000;
- time += tv.tv_usec / 1000;
-#endif
- return time;
-}
-
-//------------------------------------------------------------------------------
-// condition_variable
-//------------------------------------------------------------------------------
-// NOTE 1: The Win32 implementation of the condition_variable class is based on
-// the corresponding implementation in GLFW, which in turn is based on a
-// description by Douglas C. Schmidt and Irfan Pyarali:
-// http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
-//
-// NOTE 2: Windows Vista actually has native support for condition variables
-// (InitializeConditionVariable, WakeConditionVariable, etc), but we want to
-// be portable with pre-Vista Windows versions, so TinyThread++ does not use
-// Vista condition variables.
-//------------------------------------------------------------------------------
-
-#if defined(_TTHREAD_WIN32_)
-#define _CONDITION_EVENT_ONE 0
-#define _CONDITION_EVENT_ALL 1
-#endif
-
-#if defined(_TTHREAD_WIN32_)
-condition_variable::condition_variable() : mWaitersCount(0) {
- mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL);
- mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL);
- InitializeCriticalSection(&mWaitersCountLock);
-}
-#endif
-
-#if defined(_TTHREAD_WIN32_)
-condition_variable::~condition_variable() {
- CloseHandle(mEvents[_CONDITION_EVENT_ONE]);
- CloseHandle(mEvents[_CONDITION_EVENT_ALL]);
- DeleteCriticalSection(&mWaitersCountLock);
-}
-#endif
-
-#if defined(_TTHREAD_WIN32_)
-void condition_variable::_wait(unsigned int ms) {
- if (ms <= 0)
- ms = INFINITE;
- // Wait for either event to become signaled due to notify_one() or
- // notify_all() being called
- int result = WaitForMultipleObjects(2, mEvents, FALSE, ms);
- if (result == WAIT_FAILED) {
- LPVOID lpMsgBuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL);
-// UM_LOG_ERR("%s", lpMsgBuf);
- LocalFree(lpMsgBuf);
-
- }
-
- // Check if we are the last waiter
- EnterCriticalSection(&mWaitersCountLock);
- -- mWaitersCount;
- bool lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) &&
- (mWaitersCount == 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we are the last waiter to be notified to stop waiting, reset the event
- if(lastWaiter)
- ResetEvent(mEvents[_CONDITION_EVENT_ALL]);
-}
-#endif
-
-#if defined(_TTHREAD_WIN32_)
-void condition_variable::notify_one() {
- // Are there any waiters?
- EnterCriticalSection(&mWaitersCountLock);
- bool haveWaiters = (mWaitersCount > 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we have any waiting threads, send them a signal
- if(haveWaiters)
- SetEvent(mEvents[_CONDITION_EVENT_ONE]);
-}
-#endif
-
-#if defined(_TTHREAD_WIN32_)
-void condition_variable::notify_all() {
- // Are there any waiters?
- EnterCriticalSection(&mWaitersCountLock);
- bool haveWaiters = (mWaitersCount > 0);
- LeaveCriticalSection(&mWaitersCountLock);
-
- // If we have any waiting threads, send them a signal
- if(haveWaiters)
- SetEvent(mEvents[_CONDITION_EVENT_ALL]);
-}
-#endif
-
-
-//------------------------------------------------------------------------------
-// POSIX pthread_t to unique thread::id mapping logic.
-// Note: Here we use a global thread safe std::map to convert instances of
-// pthread_t to small thread identifier numbers (unique within one process).
-// This method should be portable across different POSIX implementations.
-//------------------------------------------------------------------------------
-
-#if defined(_TTHREAD_POSIX_)
-static thread::id _pthread_t_to_ID(const pthread_t &aHandle) {
- static mutex idMapLock;
- static std::map<pthread_t, unsigned long int> idMap;
- static unsigned long int idCount(1);
-
- lock_guard<mutex> guard(idMapLock);
- if(idMap.find(aHandle) == idMap.end())
- idMap[aHandle] = idCount ++;
- return thread::id(idMap[aHandle]);
-}
-#endif // _TTHREAD_POSIX_
-
-
-//------------------------------------------------------------------------------
-// thread
-//------------------------------------------------------------------------------
-
-/// Information to pass to the new thread (what to run).
-struct _thread_start_info {
- void (*mFunction)(void *); ///< Pointer to the function to be executed.
- void * mArg; ///< Function argument for the thread function.
- thread * mThread; ///< Pointer to the thread object.
-};
-
-// Thread wrapper function.
-#if defined(_TTHREAD_WIN32_)
-unsigned WINAPI thread::wrapper_function(void * aArg)
-#elif defined(_TTHREAD_POSIX_)
-void * thread::wrapper_function(void * aArg)
-#endif
-{
- // Get thread startup information
- _thread_start_info * ti = (_thread_start_info *) aArg;
-
- try {
- // Call the actual client thread function
- ti->mFunction(ti->mArg);
- } catch(...) {
- // Uncaught exceptions will terminate the application (default behavior
- // according to C++11)
- std::terminate();
- }
-
- // The thread is no longer executing
- lock_guard<mutex> guard(ti->mThread->mDataMutex);
- ti->mThread->mNotAThread = true;
-
- // The thread is responsible for freeing the startup information
- delete ti;
-
- return 0;
-}
-
-thread::thread(void (*aFunction)(void *), void * aArg) {
- // Serialize access to this thread structure
- lock_guard<mutex> guard(mDataMutex);
-
- // Fill out the thread startup information (passed to the thread wrapper,
- // which will eventually free it)
- _thread_start_info * ti = new _thread_start_info;
- ti->mFunction = aFunction;
- ti->mArg = aArg;
- ti->mThread = this;
-
- // The thread is now alive
- mNotAThread = false;
-
- // Create the thread
-#if defined(_TTHREAD_WIN32_)
- mHandle = (HANDLE) _beginthreadex(0, 0, wrapper_function, (void *) ti, 0, &mWin32ThreadID);
-#elif defined(_TTHREAD_POSIX_)
- if(pthread_create(&mHandle, NULL, wrapper_function, (void *) ti) != 0)
- mHandle = 0;
-#endif
-
- // Did we fail to create the thread?
- if(!mHandle) {
- mNotAThread = true;
- delete ti;
- }
-}
-
-thread::~thread() {
- if(joinable())
- std::terminate();
-}
-
-void thread::join() {
- if(joinable()) {
-#if defined(_TTHREAD_WIN32_)
- WaitForSingleObject(mHandle, INFINITE);
- CloseHandle(mHandle);
-#elif defined(_TTHREAD_POSIX_)
- pthread_join(mHandle, NULL);
-#endif
- }
-}
-
-bool thread::joinable() const {
- mDataMutex.lock();
- bool result = !mNotAThread;
- mDataMutex.unlock();
- return result;
-}
-
-void thread::detach() {
- mDataMutex.lock();
- if(!mNotAThread) {
-#if defined(_TTHREAD_WIN32_)
- CloseHandle(mHandle);
-#elif defined(_TTHREAD_POSIX_)
- pthread_detach(mHandle);
-#endif
- mNotAThread = true;
- }
- mDataMutex.unlock();
-}
-
-thread::id thread::get_id() const {
- if(!joinable())
- return id();
-#if defined(_TTHREAD_WIN32_)
- return id((unsigned long int) mWin32ThreadID);
-#elif defined(_TTHREAD_POSIX_)
- return _pthread_t_to_ID(mHandle);
-#endif
-}
-
-unsigned thread::hardware_concurrency() {
-#if defined(_TTHREAD_WIN32_)
- SYSTEM_INFO si;
- GetSystemInfo(&si);
- return (int) si.dwNumberOfProcessors;
-#elif defined(_SC_NPROCESSORS_ONLN)
- return (int) sysconf(_SC_NPROCESSORS_ONLN);
-#elif defined(_SC_NPROC_ONLN)
- return (int) sysconf(_SC_NPROC_ONLN);
-#else
- // The standard requires this function to return zero if the number of
- // hardware cores could not be determined.
- return 0;
-#endif
-}
-
-
-//------------------------------------------------------------------------------
-// this_thread
-//------------------------------------------------------------------------------
-
-thread::id this_thread::get_id() {
-#if defined(_TTHREAD_WIN32_)
- return thread::id((unsigned long int) GetCurrentThreadId());
-#elif defined(_TTHREAD_POSIX_)
- return _pthread_t_to_ID(pthread_self());
-#endif
-}
-
-namespace chrono {
-namespace system_clock {
-uint64_t now() {
- uint64_t time = 0;
-#ifdef _WIN32
- FILETIME tv;
- GetSystemTimeAsFileTime(&tv);
- time = (((uint64_t) tv.dwHighDateTime) << 32) + tv.dwLowDateTime;
- time /= 10000;
-#else
- struct timeval tv;
- gettimeofday(&tv, NULL);
- time += tv.tv_sec * 1000;
- time += tv.tv_usec / 1000;
-#endif
- return time;
-}
-}
-}
-
-}