void* AudioPlayer::tick_s(void *ptr) { struct timespec ts; AudioPlayer* that = static_cast<AudioPlayer*>(ptr); while (true) { if (that->playing_ == false) break; that->tick_p(); if (that->playing_ == false) break; /* struct _timeb timebuffer; _ftime_s(&timebuffer); ts.tv_sec = timebuffer.time; ts.tv_nsec = timebuffer.millitm * 1000; ts.tv_nsec += 900000000; */ #if defined(_WIN32) FILETIME ft; GetSystemTimeAsFileTime(&ft); ptw32_filetime_to_timespec(&ft, &ts); ts.tv_nsec += 1000000000/30; // 1/30 of sec #elif defined(__APPLE__) struct timeval tv; gettimeofday(&tv, NULL); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; ts.tv_nsec += 1000000000/30; // 1/30 of sec #else clock_gettime(CLOCK_REALTIME, &ts); ts.tv_nsec += 1000000000/30; // 1/30 of sec #endif // sem_timedwait(&that->sem_, &ts); pthread_mutex_lock(&that->mutex2_); pthread_cond_timedwait(&that->cond_, &that->mutex2_, &ts); pthread_mutex_unlock(&that->mutex2_); } // pthread_exit(NULL); return NULL; }
int sem_timedwait (sem_t * sem, const struct timespec *abstime) /* * ------------------------------------------------------ * DOCPUBLIC * This function waits on a semaphore possibly until * 'abstime' time. * * PARAMETERS * sem * pointer to an instance of sem_t * * abstime * pointer to an instance of struct timespec * * DESCRIPTION * This function waits on a semaphore. If the * semaphore value is greater than zero, it decreases * its value by one. If the semaphore value is zero, then * the calling thread (or process) is blocked until it can * successfully decrease the value or until interrupted by * a signal. * * If 'abstime' is a NULL pointer then this function will * block until it can successfully decrease the value or * until interrupted by a signal. * * RESULTS * 0 successfully decreased semaphore, * -1 failed, error in errno * ERRNO * EINVAL 'sem' is not a valid semaphore, * ENOSYS semaphores are not supported, * EINTR the function was interrupted by a signal, * EDEADLK a deadlock condition was detected. * ETIMEDOUT abstime elapsed before success. * * ------------------------------------------------------ */ { int result = 0; #ifdef NEED_FTIME struct timespec currSysTime; #else /* NEED_FTIME */ struct _timeb currSysTime; #endif /* NEED_FTIME */ const DWORD NANOSEC_PER_MILLISEC = 1000000; const DWORD MILLISEC_PER_SEC = 1000; DWORD milliseconds; DWORD tmpAbsMilliseconds; DWORD tmpCurrMilliseconds; if (sem == NULL) { result = EINVAL; } else { if (abstime == NULL) { milliseconds = INFINITE; } else { /* * Calculate timeout as milliseconds from current system time. */ /* * subtract current system time from abstime in a way that checks * that abstime is never in the past, or is never equivalent to the * defined INFINITE value (0xFFFFFFFF). * * Assume all integers are unsigned, i.e. cannot test if less than 0. */ tmpAbsMilliseconds = abstime->tv_sec * MILLISEC_PER_SEC; tmpAbsMilliseconds += (abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; /* get current system time */ #ifdef NEED_FTIME { FILETIME ft; SYSTEMTIME st; GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); /* * GetSystemTimeAsFileTime(&ft); would be faster, * but it does not exist on WinCE */ ptw32_filetime_to_timespec(&ft, &currSysTime); } tmpCurrMilliseconds = currSysTime.tv_sec * MILLISEC_PER_SEC; tmpCurrMilliseconds += (currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; #else /* ! NEED_FTIME */ _ftime(&currSysTime); tmpCurrMilliseconds = (DWORD) currSysTime.time * MILLISEC_PER_SEC; tmpCurrMilliseconds += (DWORD) currSysTime.millitm; #endif /* NEED_FTIME */ if (tmpAbsMilliseconds > tmpCurrMilliseconds) { milliseconds = tmpAbsMilliseconds - tmpCurrMilliseconds; if (milliseconds == INFINITE) { /* Timeouts must be finite */ milliseconds--; } } else { /* The abstime given is in the past */ milliseconds = 0; } } #ifdef NEED_SEM result = (pthreadCancelableTimedWait ((*sem)->event, milliseconds)); #else /* NEED_SEM */ result = (pthreadCancelableTimedWait ((*sem)->sem, milliseconds)); #endif } if (result != 0) { errno = result; return -1; } #ifdef NEED_SEM ptw32_decrease_semaphore (sem); #endif /* NEED_SEM */ return 0; } /* sem_timedwait */
INLINE #endif /* PTW32_BUILD_INLINED */ DWORD ptw32_relmillisecs (const struct timespec * abstime) { const int64_t NANOSEC_PER_MILLISEC = 1000000; const int64_t MILLISEC_PER_SEC = 1000; DWORD milliseconds; int64_t tmpAbsMilliseconds; int64_t tmpCurrMilliseconds; #if defined(NEED_FTIME) struct timespec currSysTime; FILETIME ft; SYSTEMTIME st; #else /* ! NEED_FTIME */ #if ( defined(_MSC_VER) && _MSC_VER >= 1300 ) /* MSVC7+ */ || \ ( defined(PTW32_CONFIG_MINGW) && __MSVCRT_VERSION__ >= 0x0601 ) struct __timeb64 currSysTime; #else struct _timeb currSysTime; #endif #endif /* NEED_FTIME */ /* * Calculate timeout as milliseconds from current system time. */ /* * subtract current system time from abstime in a way that checks * that abstime is never in the past, or is never equivalent to the * defined INFINITE value (0xFFFFFFFF). * * Assume all integers are unsigned, i.e. cannot test if less than 0. */ tmpAbsMilliseconds = (int64_t)abstime->tv_sec * MILLISEC_PER_SEC; tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; /* get current system time */ #if defined(NEED_FTIME) GetSystemTime(&st); SystemTimeToFileTime(&st, &ft); /* * GetSystemTimeAsFileTime(&ft); would be faster, * but it does not exist on WinCE */ ptw32_filetime_to_timespec(&ft, &currSysTime); tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC; tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; #else /* ! NEED_FTIME */ #if defined(_MSC_VER) && _MSC_VER >= 1400 /* MSVC8+ */ _ftime64_s(&currSysTime); #elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) /* MSVC7+ */ || \ ( defined(PTW32_CONFIG_MINGW) && __MSVCRT_VERSION__ >= 0x0601 ) _ftime64(&currSysTime); #else _ftime(&currSysTime); #endif tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC; tmpCurrMilliseconds += (int64_t) currSysTime.millitm; #endif /* NEED_FTIME */ if (tmpAbsMilliseconds > tmpCurrMilliseconds) { milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds); if (milliseconds == INFINITE) { /* Timeouts must be finite */ milliseconds--; } } else { /* The abstime given is in the past */ milliseconds = 0; } return milliseconds; }