Merge "Fix Condition::waitRelative."

This commit is contained in:
Elliott Hughes 2016-04-05 16:43:25 +00:00 committed by Gerrit Code Review
commit 0d6bb55a39

View file

@ -106,30 +106,40 @@ inline status_t Condition::wait(Mutex& mutex) {
return -pthread_cond_wait(&mCond, &mutex.mMutex); return -pthread_cond_wait(&mCond, &mutex.mMutex);
} }
inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) { inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {
#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
struct timespec ts;
ts.tv_sec = reltime/1000000000;
ts.tv_nsec = reltime%1000000000;
return -pthread_cond_timedwait_relative_np(&mCond, &mutex.mMutex, &ts);
#else // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
struct timespec ts; struct timespec ts;
#if defined(__linux__) #if defined(__linux__)
clock_gettime(CLOCK_REALTIME, &ts); clock_gettime(CLOCK_REALTIME, &ts);
#else // __APPLE__ #else // __APPLE__
// we don't support the clocks here. // Apple doesn't support POSIX clocks.
struct timeval t; struct timeval t;
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
ts.tv_sec = t.tv_sec; ts.tv_sec = t.tv_sec;
ts.tv_nsec= t.tv_usec*1000; ts.tv_nsec = t.tv_usec*1000;
#endif #endif
ts.tv_sec += reltime/1000000000;
ts.tv_nsec+= reltime%1000000000; // On 32-bit devices, tv_sec is 32-bit, but `reltime` is 64-bit.
if (ts.tv_nsec >= 1000000000) { int64_t reltime_sec = reltime/1000000000;
ts.tv_nsec += reltime%1000000000;
if (reltime_sec < INT64_MAX && ts.tv_nsec >= 1000000000) {
ts.tv_nsec -= 1000000000; ts.tv_nsec -= 1000000000;
ts.tv_sec += 1; ++reltime_sec;
} }
int64_t time_sec = ts.tv_sec;
if (time_sec > INT64_MAX - reltime_sec) {
time_sec = INT64_MAX;
} else {
time_sec += reltime_sec;
}
#if defined(__LP64__)
ts.tv_sec = time_sec;
#else
ts.tv_sec = (time_sec > INT32_MAX) ? INT32_MAX : time_sec;
#endif
return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts); return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);
#endif // HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE
} }
inline void Condition::signal() { inline void Condition::signal() {
/* /*