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).
This commit is contained in:
Daniel Stone 2006-10-25 23:57:00 +03:00 committed by Daniel Stone
parent d3e57faffe
commit d285833290
3 changed files with 79 additions and 6 deletions

View File

@ -515,7 +515,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
dnl Core modules for most extensions, et al. 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" REQUIRED_LIBS="xfont xau fontenc"
AM_CONDITIONAL(XV, [test "x$XV" = xyes]) AM_CONDITIONAL(XV, [test "x$XV" = xyes])
@ -873,9 +873,46 @@ PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}" XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm" XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
AC_SUBST([XSERVER_LIBS])
AC_SUBST([SYS_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 <time.h>
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 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 dnl we need to replicate that here until those can all be fixed
AC_MSG_CHECKING([if SVR4 needs to be defined]) 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" 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_DEFINE_UNQUOTED(X_BYTE_ORDER,[$ENDIAN],[Endian order])
AC_SUBST([XSERVER_LIBS])
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------
dnl DDX section. dnl DDX section.
dnl --------------------------------------------------------------------------- dnl ---------------------------------------------------------------------------

View File

@ -445,4 +445,7 @@
/* Define to 1 if modules should avoid the libcwrapper */ /* Define to 1 if modules should avoid the libcwrapper */
#undef NO_LIBCWRAPPER #undef NO_LIBCWRAPPER
/* Have a monotonic clock from clock_gettime() */
#undef MONOTONIC_CLOCK
#endif /* _DIX_CONFIG_H_ */ #endif /* _DIX_CONFIG_H_ */

View File

@ -53,6 +53,19 @@ OR PERFORMANCE OF THIS SOFTWARE.
#include <dix-config.h> #include <dix-config.h>
#endif #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__ #ifdef __CYGWIN__
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
@ -92,7 +105,6 @@ OR PERFORMANCE OF THIS SOFTWARE.
#if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4) #if !defined(SYSV) && !defined(WIN32) && !defined(Lynx) && !defined(QNX4)
#include <sys/resource.h> #include <sys/resource.h>
#endif #endif
#include <time.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> /* for isspace */ #include <ctype.h> /* for isspace */
#include <stdarg.h> #include <stdarg.h>
@ -256,6 +268,8 @@ int auditTrailLevel = 1;
_X_EXPORT Bool Must_have_memory = FALSE; _X_EXPORT Bool Must_have_memory = FALSE;
static int monotonic_usable = -1;
#ifdef AIXV3 #ifdef AIXV3
int SyncOn = 0; int SyncOn = 0;
extern int SelectWaitTime; extern int SelectWaitTime;
@ -535,10 +549,27 @@ GiveUp(int sig)
_X_EXPORT CARD32 _X_EXPORT CARD32
GetTimeInMillis(void) GetTimeInMillis(void)
{ {
struct timeval tp; struct timeval tv;
#ifdef MONOTONIC_CLOCK
struct timespec tp;
int spare = 0;
X_GETTIMEOFDAY(&tp); if (_X_UNLIKELY(monotonic_usable == -1)) {
return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); 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 _X_EXPORT void