By default the X server will try CLOCK_MONOTONIC_COARSE before CLOCK_MONOTONIC, while A Wayland compositor may only support getting their timestamps from the CLOCK_MONOTONIC clock. This causes various issues since it may happen that a timestamp from CLOCK_MONOTONIC retrieved before a sending an X request will still be "later" than the timestamp the X server than gets after receiving the request, due to the fact that CLOCK_MONOTONIC_COARSE has a lower resolution.
To avoid these issues, make Xwayland always use CLOCK_MONOTONIC, so that it becomes possible for Wayland compositor only supporting CLOCK_MONOTONIC and X server to use the same clock. Signed-off-by: Jonas Ådahl <[email protected]> Acked-by: Daniel Stone <[email protected]> --- Here is a version that just simply forces it. I figured it would be annoynig to have to detect the Xwayland version and append a command line given the version. Let me know if a command line argument version of the patch is preferred by anyone. Jonas configure.ac | 4 ++++ hw/xwayland/xwayland.c | 2 ++ include/os.h | 7 +++++++ os/utils.c | 24 ++++++++++++++++++++++-- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f4de90f..8cc508c 100644 --- a/configure.ac +++ b/configure.ac @@ -2471,6 +2471,10 @@ if test "x$XWAYLAND" = xyes; then AC_SUBST([XWAYLAND_LIBS]) AC_SUBST([XWAYLAND_SYS_LIBS]) + if test "x$MONOTONIC_CLOCK" != xyes; then + AC_MSG_ERROR([Xwayland requires CLOCK_MONOTONIC support.]) + fi + WAYLAND_PREFIX=`$PKG_CONFIG --variable=prefix wayland-client` AC_PATH_PROG([WAYLAND_SCANNER], [wayland-scanner],, [${WAYLAND_PREFIX}/bin$PATH_SEPARATOR$PATH]) diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 3d36205..cad4e9d 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -32,6 +32,7 @@ #include <misyncshm.h> #include <compositeext.h> #include <glx_extinit.h> +#include <os.h> void ddxGiveUp(enum ExitCode error) @@ -47,6 +48,7 @@ AbortDDX(enum ExitCode error) void OsVendorInit(void) { + ForceClockId(CLOCK_MONOTONIC); } void diff --git a/include/os.h b/include/os.h index 461d5d6..f37ad5d 100644 --- a/include/os.h +++ b/include/os.h @@ -51,6 +51,9 @@ SOFTWARE. #include <stdarg.h> #include <stdint.h> #include <string.h> +#ifdef MONOTONIC_CLOCK +#include <time.h> +#endif #define SCREEN_SAVER_ON 0 #define SCREEN_SAVER_OFF 1 @@ -180,6 +183,10 @@ extern _X_EXPORT void ListenOnOpenFD(int /* fd */ , int /* noxauth */ ); extern _X_EXPORT Bool AddClientOnOpenFD(int /* fd */ ); +#ifdef MONOTONIC_CLOCK +extern _X_EXPORT void ForceClockId(clockid_t /* forced_clockid */); +#endif + extern _X_EXPORT CARD32 GetTimeInMillis(void); extern _X_EXPORT CARD64 GetTimeInMicros(void); diff --git a/os/utils.c b/os/utils.c index e48d9f8..2c4a588 100644 --- a/os/utils.c +++ b/os/utils.c @@ -210,6 +210,10 @@ sig_atomic_t inSignalContext = FALSE; #define HAS_SAVED_IDS_AND_SETEUID #endif +#ifdef MONOTONIC_CLOCK +static clockid_t clockid; +#endif + OsSigHandlerPtr OsSignal(int sig, OsSigHandlerPtr handler) { @@ -427,6 +431,24 @@ GiveUp(int sig) errno = olderrno; } +#ifdef MONOTONIC_CLOCK +void +ForceClockId(clockid_t forced_clockid) +{ + struct timespec tp; + + BUG_RETURN (clockid); + + clockid = forced_clockid; + + if (clock_gettime(clockid, &tp) != 0) { + FatalError("Forced clock id failed to retrieve current time: %s\n", + strerror(errno)); + return; + } +} +#endif + #if (defined WIN32 && defined __MINGW32__) || defined(__CYGWIN__) CARD32 GetTimeInMillis(void) @@ -446,7 +468,6 @@ GetTimeInMillis(void) #ifdef MONOTONIC_CLOCK struct timespec tp; - static clockid_t clockid; if (!clockid) { #ifdef CLOCK_MONOTONIC_COARSE @@ -475,7 +496,6 @@ GetTimeInMicros(void) struct timeval tv; #ifdef MONOTONIC_CLOCK struct timespec tp; - static clockid_t clockid; if (!clockid) { if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) -- 2.4.3 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
