summaryrefslogtreecommitdiff
path: root/os
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-10-26 00:28:30 +0300
committerDaniel Stone <daniels@endtroducing.fooishbar.org>2006-10-26 00:28:30 +0300
commitcdc8a4b7b2f099b8860a54c5c9f488e6f7c4913a (patch)
tree9cf800ad11ab48210350585088529aaebc86feca /os
parent3da918a16c8908fdfaf89f2a1bcaec19e01528a9 (diff)
parentd285833290316cb5dd1e7f1e52c96be3e9cf21cd (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.c34
-rw-r--r--os/utils.c39
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