75 #define _strdup strdup
93 , m_yieldOnZeroSleep(true)
95 , m_stopHandle(::CreateEvent(NULL, TRUE, FALSE, NULL))
96 , m_running(::CreateEvent(NULL, TRUE, FALSE, NULL))
104 pthread_attr_init(&
m_attr);
122 ::CloseHandle(m_stopHandle);
124 pthread_attr_destroy(&
m_attr);
130 void StandardThread::terminateThread()
133 ::TerminateThread(
m_thread, DWORD(-1));
147 if (::GetExitCodeThread(m_thread, &exitCode))
149 if (exitCode == STILL_ACTIVE)
154 return (pthread_kill(m_thread, 0) == 0);
165 switch (::WaitForSingleObject(m_running, 0))
199 ::SetThreadPriority(
m_thread, (
int) pri);
201 #ifdef _POSIX_PRIORITY_SCHEDULING
204 struct sched_param
param;
222 param.sched_priority = sched_get_priority_max(policy);
226 param.sched_priority = sched_get_priority_max(policy);
230 int32_t min_prio = sched_get_priority_min(policy);
231 int32_t max_prio = sched_get_priority_max(policy);
233 if (min_prio < 0 || max_prio < 0)
239 param.sched_priority = (
int32_t)(min_prio + (pri * priostep));
295 ::ResetEvent(m_stopHandle);
324 ::SetEvent(m_stopHandle);
325 ::SetThreadPriority(
m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
366 DWORD lastErr = GetLastError();
389 if (pthread_join(m_thread, NULL))
437 int64_t sleepStart = XsTimeStamp::nowMs();
441 int64_t timePassed = XsTimeStamp::nowMs() - sleepStart;
445 else if (remaining <= 0)
448 XsTime::msleep((
uint32_t) remaining);
464 , m_stop(::CreateEvent(NULL, TRUE, FALSE, NULL))
465 , m_running(::CreateEvent(NULL, TRUE, FALSE, NULL))
466 , m_reset(::CreateEvent(NULL, TRUE, FALSE, NULL))
479 pthread_attr_init(&
m_attr);
498 pthread_attr_destroy(&
m_attr);
506 if (::GetExitCodeThread(m_thread, &exitCode))
507 return (exitCode == STILL_ACTIVE);
512 return (pthread_kill(m_thread, 0) == 0);
522 switch (::WaitForSingleObject(m_running, 0))
528 switch (::WaitForSingleObject(m_stop, 0))
598 ::SetThreadPriority(m_thread, THREAD_PRIORITY_ABOVE_NORMAL);
602 if (::CloseHandle(m_thread) == 0)
604 DWORD lastErr = GetLastError();
611 struct sched_param
param;
614 rv = pthread_getschedparam(m_thread, &policy, &
param);
625 param.sched_priority = sched_get_priority_max(policy);
627 rv = pthread_setschedparam(m_thread, policy, &
param);
642 rv = pthread_join(m_thread, NULL);
688 switch (::WaitForMultipleObjects(2, hlist, FALSE, timeout))
696 case WAIT_OBJECT_0+1:
713 timeout =
static_cast<uint32_t>((toTime - XsTimeStamp::now()).msTime());
763 m_handleList[i] = otherHandles[i];
764 m_handleList[
m_nofHandles - 1] = CreateSemaphore(NULL, initVal, 0x7fffffff, NULL);
771 delete[] m_handleList;
783 DWORD r = WaitForMultipleObjects(
m_nofHandles, m_handleList, FALSE, timeout);
784 if (r == WAIT_TIMEOUT)
788 if (r != WAIT_TIMEOUT)
797 ReleaseSemaphore(m_handleList[m_nofHandles - 1], increment, &prev);
807 #if defined(SEM_VALUE_MAX) && INT32_MAX > SEM_VALUE_MAX
808 if (initVal > SEM_VALUE_MAX)
809 initVal = SEM_VALUE_MAX;
812 uint64_t
id = (uint64_t)
this;
817 sprintf(semname,
"%" PRINTF_INT64_MODIFIER
"x",
id);
819 m_handle = sem_open(semname, O_EXCL | O_CREAT, S_IRWXU, initVal);
825 perror(
"opening semaphore");
851 #if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
854 clock_gettime(CLOCK_REALTIME, &ts);
856 int64_t
s = ms / 1000;
860 int64_t ns = ts.tv_nsec + (ms * 1000000);
862 ts.tv_sec += ns / 1000000000L;
863 ts.tv_nsec = ns % 1000000000L;
865 return sem_timedwait(
m_handle, &ts) == 0;
869 while (XsTimeStamp::now() < end)
885 sem_getvalue(m_handle, &prev);
886 for (
int i = 0; i < increment; i++)
894 for (
int i = 0; i < increment; i++)
909 #ifndef CLOCK_REALTIME
910 #define CLOCK_REALTIME 0
912 static int clock_gettime(
int clk_id,
struct timespec* tp)
917 int rv = gettimeofday(&now, NULL);
921 tp->tv_sec = now.tv_sec;
922 tp->tv_nsec = now.tv_usec * 1000;
932 InitializeConditionVariable(&
m_cond);
935 #if !defined(__APPLE__) && (defined(_POSIX_CLOCK_SELECTION) || defined(_SC_CLOCK_SELECTION)) && !defined(ANDROID)
957 pthread_cond_destroy(&
m_cond);
970 WakeConditionVariable(&
m_cond);
972 pthread_cond_signal(&
m_cond);
980 WakeAllConditionVariable(&
m_cond);
982 pthread_cond_broadcast(&
m_cond);
1018 static const int64_t NANOS_PER_MILLI = 1000000;
1019 static const int64_t NANOS_PER_ONE = NANOS_PER_MILLI * 1000;
1021 struct timespec time;
1026 nsec = time.tv_nsec + timeout * NANOS_PER_MILLI;
1027 time.tv_nsec = nsec % NANOS_PER_ONE;
1028 time.tv_sec += nsec / NANOS_PER_ONE;
1038 , m_terminating(false)
1040 m_event = ::CreateEventA(NULL, TRUE, FALSE, NULL);
1053 ::CloseHandle(m_event);
1054 m_event = INVALID_HANDLE_VALUE;
1067 switch (::WaitForSingleObject(m_event, INFINITE))
1069 case WAIT_ABANDONED:
1087 ::SetEvent(m_event);
1097 ::ResetEvent(m_event);
1102 , m_terminating(false)
1104 pthread_mutex_init(&
m_mutex, 0);
1105 pthread_cond_init(&
m_cond, 0);
1112 pthread_cond_destroy(&
m_cond);
1113 pthread_mutex_destroy(&
m_mutex);
1128 pthread_mutex_unlock(&
m_mutex);
1140 pthread_cond_signal(&
m_cond);
1141 pthread_mutex_unlock(&
m_mutex);
1154 pthread_mutex_unlock(&
m_mutex);