diff -r 7494f3972726 Makefile.pre.in --- a/Makefile.pre.in Tue Feb 03 15:12:13 2015 +0100 +++ b/Makefile.pre.in Mon Feb 09 23:15:07 2015 +0100 @@ -838,7 +838,7 @@ Objects/setobject.o: $(srcdir)/Objects/s $(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) $(OPCODETARGETGEN) $(OPCODETARGETS_H) -Python/ceval.o: $(OPCODETARGETS_H) $(srcdir)/Python/ceval_gil.h +Python/ceval.o: $(OPCODETARGETS_H) $(srcdir)/Python/ceval_gil.h $(srcdir)/Python/condvar.h Python/frozen.o: Python/importlib.h @@ -1626,7 +1626,7 @@ patchcheck: # Dependencies -Python/thread.o: @THREADHEADERS@ +Python/thread.o: @THREADHEADERS@ $(srcdir)/Python/condvar.h # Declare targets that aren't real files .PHONY: all build_all sharedmods oldsharedmods test quicktest diff -r 7494f3972726 Python/condvar.h --- a/Python/condvar.h Tue Feb 03 15:12:13 2015 +0100 +++ b/Python/condvar.h Mon Feb 09 23:15:07 2015 +0100 @@ -59,20 +59,6 @@ #include -#define PyCOND_ADD_MICROSECONDS(tv, interval) \ -do { /* TODO: add overflow and truncation checks */ \ - tv.tv_usec += (long) interval; \ - tv.tv_sec += tv.tv_usec / 1000000; \ - tv.tv_usec %= 1000000; \ -} while (0) - -/* We assume all modern POSIX systems have gettimeofday() */ -#ifdef GETTIMEOFDAY_NO_TZ -#define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv) -#else -#define PyCOND_GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL) -#endif - /* The following functions return 0 on success, nonzero on error */ #define PyMUTEX_T pthread_mutex_t #define PyMUTEX_INIT(mut) pthread_mutex_init((mut), NULL) @@ -81,22 +67,50 @@ do { /* TODO: add overflow and truncatio #define PyMUTEX_UNLOCK(mut) pthread_mutex_unlock(mut) #define PyCOND_T pthread_cond_t -#define PyCOND_INIT(cond) pthread_cond_init((cond), NULL) #define PyCOND_FINI(cond) pthread_cond_destroy(cond) #define PyCOND_SIGNAL(cond) pthread_cond_signal(cond) #define PyCOND_BROADCAST(cond) pthread_cond_broadcast(cond) #define PyCOND_WAIT(cond, mut) pthread_cond_wait((cond), (mut)) +#define MONOTONIC + +Py_LOCAL_INLINE(int) +PyCOND_INIT(PyCOND_T *cond) +{ + pthread_condattr_t attr; + int err; + + (void)pthread_condattr_init(&attr); +#ifdef MONOTONIC + err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + if (err) + return err; +#endif + err = pthread_cond_init(cond, &attr); + (void)pthread_condattr_destroy(&attr); + return err; +} + /* return 0 for success, 1 on timeout, -1 on error */ Py_LOCAL_INLINE(int) PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, PY_LONG_LONG us) { int r; struct timespec ts; - struct timeval deadline; + _PyTime_timeval deadline; - PyCOND_GETTIMEOFDAY(&deadline); - PyCOND_ADD_MICROSECONDS(deadline, us); +#ifdef MONOTONIC + _PyTime_monotonic(&deadline); +#else + _PyTime_gettimeofday(&deadline); +#endif + + /* TODO: add overflow and truncation checks */ + assert(us <= LONG_MAX); + deadline.tv_usec += (long)us; + deadline.tv_sec += deadline.tv_usec / 1000000; + deadline.tv_usec %= 1000000; + ts.tv_sec = deadline.tv_sec; ts.tv_nsec = deadline.tv_usec * 1000; diff -r 7494f3972726 Python/thread_pthread.h --- a/Python/thread_pthread.h Tue Feb 03 15:12:13 2015 +0100 +++ b/Python/thread_pthread.h Mon Feb 09 23:15:07 2015 +0100 @@ -84,6 +84,7 @@ defined(HAVE_SEM_TIMEDWAIT)) # define USE_SEMAPHORES #else +# define MONOTONIC # undef USE_SEMAPHORES #endif @@ -99,18 +100,16 @@ # define SET_THREAD_SIGMASK sigprocmask #endif - -/* We assume all modern POSIX systems have gettimeofday() */ -#ifdef GETTIMEOFDAY_NO_TZ -#define GETTIMEOFDAY(ptv) gettimeofday(ptv) +#ifdef MONOTONIC +#define GETTIME(ptv) _PyTime_monotonic(ptv) #else -#define GETTIMEOFDAY(ptv) gettimeofday(ptv, (struct timezone *)NULL) +#define GETTIME(ptv) _PyTime_gettimeofday(ptv) #endif #define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ do { \ - struct timeval tv; \ - GETTIMEOFDAY(&tv); \ + _PyTime_timeval tv; \ + GETTIME(&tv); \ tv.tv_usec += microseconds % 1000000; \ tv.tv_sec += microseconds / 1000000; \ tv.tv_sec += tv.tv_usec / 1000000; \ @@ -405,6 +404,7 @@ PyThread_allocate_lock(void) { pthread_lock *lock; int status, error = 0; + pthread_condattr_t attr; dprintf(("PyThread_allocate_lock called\n")); if (!initialized) @@ -425,9 +425,14 @@ PyThread_allocate_lock(void) will cause errors. */ _Py_ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(&lock->mut); - status = pthread_cond_init(&lock->lock_released, - pthread_condattr_default); + pthread_condattr_init(&attr); +#ifdef MONOTONIC + status = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + CHECK_STATUS("pthread_condattr_setclock"); +#endif + status = pthread_cond_init(&lock->lock_released, &attr); CHECK_STATUS("pthread_cond_init"); + pthread_condattr_destroy(&attr); if (error) { PyMem_RawFree((void *)lock);