diff options
author | Daniel Stone <daniel@fooishbar.org> | 2006-10-26 00:28:30 +0300 |
---|---|---|
committer | Daniel Stone <daniels@endtroducing.fooishbar.org> | 2006-10-26 00:28:30 +0300 |
commit | cdc8a4b7b2f099b8860a54c5c9f488e6f7c4913a (patch) | |
tree | 9cf800ad11ab48210350585088529aaebc86feca /os | |
parent | 3da918a16c8908fdfaf89f2a1bcaec19e01528a9 (diff) | |
parent | d285833290316cb5dd1e7f1e52c96be3e9cf21cd (diff) |
Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-hotplug
Diffstat (limited to 'os')
-rw-r--r-- | os/WaitFor.c | 34 | ||||
-rw-r--r-- | os/utils.c | 39 |
2 files changed, 66 insertions, 7 deletions
diff --git a/os/WaitFor.c b/os/WaitFor.c index 045767809..896fdf15d 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -119,11 +119,13 @@ mffs(fd_mask mask) struct _OsTimerRec { OsTimerPtr next; CARD32 expires; + CARD32 delta; OsTimerCallback callback; pointer arg; }; static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); +static void CheckAllTimers(CARD32 now); static OsTimerPtr timers = NULL; /***************** @@ -200,6 +202,11 @@ WaitForSomething(int *pClientsReady) { now = GetTimeInMillis(); timeout = timers->expires - now; + /* time has rewound. reset the timers. */ + if (timeout > timers->delta) { + CheckAllTimers(now); + timeout = timers->expires - now; + } if (timeout < 0) timeout = 0; waittime.tv_sec = timeout / MILLI_PER_SECOND; @@ -426,6 +433,20 @@ ANYSET(FdMask *src) } #endif +/* If time has rewound, re-run every affected timer. + * TimerForce will change timer->next, but it will _generally_ only + * promote timers in the list, meaning that we should still be + * walking every timer. */ +static void +CheckAllTimers(CARD32 now) +{ + OsTimerPtr timer; + + for (timer = timers; timer; timer = timer->next) { + if (timer->expires - now > timer->delta) + TimerForce(timer); + } +} static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) @@ -467,8 +488,13 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis, } if (!millis) return timer; - if (!(flags & TimerAbsolute)) + if (flags & TimerAbsolute) { + timer->delta = millis - now; + } + else { + timer->delta = millis; millis += now; + } timer->expires = millis; timer->callback = func; timer->arg = arg; @@ -481,8 +507,10 @@ TimerSet(OsTimerPtr timer, int flags, CARD32 millis, } for (prev = &timers; *prev && (int) ((*prev)->expires - millis) <= 0; - prev = &(*prev)->next) - ; + prev = &(*prev)->next) { + if ((*prev)->expires - now > (*prev)->delta) + CheckAllTimers(now); + } timer->next = *prev; *prev = timer; return timer; diff --git a/os/utils.c b/os/utils.c index 31ae26a18..379291c9d 100644 --- a/os/utils.c +++ b/os/utils.c @@ -53,6 +53,19 @@ OR PERFORMANCE OF THIS SOFTWARE. #include <dix-config.h> #endif +/* The world's most shocking hack, to ensure we get clock_gettime() and + * CLOCK_MONOTONIC. */ +#ifdef _POSIX_C_SOURCE +#define _SAVED_POSIX_C_SOURCE _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif +#define _POSIX_C_SOURCE 199309L +#include <time.h> +#undef _POSIX_C_SOURCE +#ifdef _SAVED_POSIX_C_SOURCE +#define _POSIX_C_SOURCE _SAVED_POSIX_C_SOURCE +#endif + #ifdef __CYGWIN__ #include <stdlib.h> #include <signal.h> @@ -92,7 +105,6 @@ OR PERFORMANCE OF THIS SOFTWARE. #if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4) #include <sys/resource.h> #endif -#include <time.h> #include <sys/stat.h> #include <ctype.h> /* for isspace */ #include <stdarg.h> @@ -256,6 +268,8 @@ int auditTrailLevel = 1; _X_EXPORT Bool Must_have_memory = FALSE; +static int monotonic_usable = -1; + #ifdef AIXV3 int SyncOn = 0; extern int SelectWaitTime; @@ -535,10 +549,27 @@ GiveUp(int sig) _X_EXPORT CARD32 GetTimeInMillis(void) { - struct timeval tp; + struct timeval tv; +#ifdef MONOTONIC_CLOCK + struct timespec tp; + int spare = 0; + + if (_X_UNLIKELY(monotonic_usable == -1)) { + if (clock_gettime(0, &tp) == 0 && + clock_getcpuclockid(0, &spare) == 0) + monotonic_usable = 1; + else + monotonic_usable = 0; + } + + if (_X_LIKELY(monotonic_usable == 1)) { + if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) + return (tp.tv_sec * 1000) + (tp.tv_nsec / 1000000); + } +#endif - X_GETTIMEOFDAY(&tp); - return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); + X_GETTIMEOFDAY(&tv); + return(tv.tv_sec * 1000) + (tv.tv_usec / 1000); } _X_EXPORT void |