From 828c34e83ccdf3bcd2844d5af8b0cac4164b04ab Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 24 Oct 2006 17:23:02 -0700 Subject: [PATCH 1/4] Byte swap RRSelectInput enable flags. --- randr/randr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/randr/randr.c b/randr/randr.c index 946aad31d..d0bbfe50f 100644 --- a/randr/randr.c +++ b/randr/randr.c @@ -1187,6 +1187,7 @@ SProcRRSelectInput (ClientPtr client) swaps(&stuff->length, n); swapl(&stuff->window, n); + swaps(&stuff->enable, n); return ProcRRSelectInput(client); } From becbda6d519a11c2c211afb8d46f9ea1a2676bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 25 Oct 2006 11:39:27 +0200 Subject: [PATCH 2/4] Fix test for Option "IgnoreABI". This option has plenty of potential for wasting the time of bug triagers without pretending it's always on. --- hw/xfree86/common/xf86Config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 87b8a0b72..bff9233f8 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -895,7 +895,7 @@ configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts) xf86GetOptValBool(FlagOptions, FLAG_ALLOW_CLOSEDOWN_GRABS, &(xf86Info.grabInfo.allowClosedown)); xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI); - if (&xf86Info.ignoreABI) { + if (xf86Info.ignoreABI) { xf86Msg(X_CONFIG, "Ignoring ABI Version\n"); } From d3e57faffee63df1424a209d0418d3a712f91ae6 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 25 Oct 2006 23:55:43 +0300 Subject: [PATCH 3/4] WaitForSomething: allow time to rewind If time rewinds dramatically, reset all the timers to fix their expiry. --- os/WaitFor.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 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; From d285833290316cb5dd1e7f1e52c96be3e9cf21cd Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Wed, 25 Oct 2006 23:57:00 +0300 Subject: [PATCH 4/4] GetTimeInMillis: spuport monotonic clock Add support for CLOCK_MONOTONIC from clock_gettime, and use that in GetTimeInMillis() if available, falling back to the old gettimeofday() implementation. This is _slightly_ faster on some 64-bit architectures, and _slightly_ slower on others (though barely measurable). --- configure.ac | 43 +++++++++++++++++++++++++++++++++++++++-- include/dix-config.h.in | 3 +++ os/utils.c | 39 +++++++++++++++++++++++++++++++++---- 3 files changed, 79 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 444b02113..0f2ddd523 100644 --- a/configure.ac +++ b/configure.ac @@ -515,7 +515,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la' XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' dnl Core modules for most extensions, et al. -REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto xproto xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto [kbproto >= 1.0.3]" +REQUIRED_MODULES="randrproto renderproto [fixesproto >= 4.0] damageproto xcmiscproto xextproto [xproto >= 7.0.9] xtrans xf86miscproto xf86vidmodeproto xf86bigfontproto [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto inputproto xf86dgaproto [kbproto >= 1.0.3]" REQUIRED_LIBS="xfont xau fontenc" AM_CONDITIONAL(XV, [test "x$XV" = xyes]) @@ -873,9 +873,46 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS]) XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm" -AC_SUBST([XSERVER_LIBS]) AC_SUBST([SYS_LIBS]) +AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], + [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt], + [have_clock_gettime=no])]) + +AC_MSG_CHECKING([for a useful monotonic clock ...]) + +if ! test "x$have_clock_gettime" = xno; then + if ! test "x$have_clock_gettime" = xyes; then + LIBS="$have_clock_gettime" + else + LIBS="" + fi + + AC_RUN_IFELSE([ +#define _POSIX_C_SOURCE 199309L +#include + +int main(int argc, char *argv[]) { + struct timespec tp; + + if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) + return 0; + else + return 1; +} + ], [MONOTONIC_CLOCK=yes], [MONOTONIC_CLOCK=no], + [MONOTONIC_CLOCK="cross compiling"]) +else + MONOTONIC_CLOCK=no +fi + +AC_MSG_RESULT([$MONOTONIC_CLOCK]) + +if test "x$MONOTONIC_CLOCK" = xyes; then + AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()]) + XSERVER_LIBS="$XSERVER_LIBS $LIBS" +fi + dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so dnl we need to replicate that here until those can all be fixed AC_MSG_CHECKING([if SVR4 needs to be defined]) @@ -890,6 +927,8 @@ AC_MSG_RESULT([yes])], AC_MSG_RESULT([no])) XSERVER_CFLAGS="$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC" AC_DEFINE_UNQUOTED(X_BYTE_ORDER,[$ENDIAN],[Endian order]) +AC_SUBST([XSERVER_LIBS]) + dnl --------------------------------------------------------------------------- dnl DDX section. dnl --------------------------------------------------------------------------- diff --git a/include/dix-config.h.in b/include/dix-config.h.in index 65c42e6af..35700e460 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -445,4 +445,7 @@ /* Define to 1 if modules should avoid the libcwrapper */ #undef NO_LIBCWRAPPER +/* Have a monotonic clock from clock_gettime() */ +#undef MONOTONIC_CLOCK + #endif /* _DIX_CONFIG_H_ */ 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 #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 +#undef _POSIX_C_SOURCE +#ifdef _SAVED_POSIX_C_SOURCE +#define _POSIX_C_SOURCE _SAVED_POSIX_C_SOURCE +#endif + #ifdef __CYGWIN__ #include #include @@ -92,7 +105,6 @@ OR PERFORMANCE OF THIS SOFTWARE. #if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4) #include #endif -#include #include #include /* for isspace */ #include @@ -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; - X_GETTIMEOFDAY(&tp); - return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); + 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(&tv); + return(tv.tv_sec * 1000) + (tv.tv_usec / 1000); } _X_EXPORT void