aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/dmx/dmxsync.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
committermarha <marha@users.sourceforge.net>2012-03-23 10:05:55 +0100
commit0f834b91a4768673833ab4917e87d86c237bb1a6 (patch)
tree363489504ed4b2d360259b8de4c9e392918e5d02 /xorg-server/hw/dmx/dmxsync.c
parentfc72edebf875378459368c5383d9023730cbca54 (diff)
downloadvcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.gz
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.tar.bz2
vcxsrv-0f834b91a4768673833ab4917e87d86c237bb1a6.zip
libX11 xserver fontconfig mesa pixman xkbcomp xkeyboard-config git update
23 Mar 2012
Diffstat (limited to 'xorg-server/hw/dmx/dmxsync.c')
-rw-r--r--xorg-server/hw/dmx/dmxsync.c400
1 files changed, 207 insertions, 193 deletions
diff --git a/xorg-server/hw/dmx/dmxsync.c b/xorg-server/hw/dmx/dmxsync.c
index 8ace59470..bf28584b4 100644
--- a/xorg-server/hw/dmx/dmxsync.c
+++ b/xorg-server/hw/dmx/dmxsync.c
@@ -1,193 +1,207 @@
-/*
- * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation on the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- *
- * The DMX server code is written to call #dmxSync() whenever an XSync()
- * might be necessary. However, since XSync() requires a two way
- * communication with the other X server, eliminating unnecessary
- * XSync() calls is a key performance optimization. Support for this
- * optimization is provided here. Statistics about XSync() calls and
- * latency are gathered in \a dmxstat.c.
- *
- * During the initial conversion from calling XSync() immediately to the
- * XSync() batching method implemented in this file, it was noted that,
- * out of more than 300 \a x11perf tests, 8 tests became more than 100
- * times faster, with 68 more than 50X faster, 114 more than 10X faster,
- * and 181 more than 2X faster. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxstat.h"
-#include "dmxlog.h"
-#include <sys/time.h>
-
-static int dmxSyncInterval = 100; /* Default interval in milliseconds */
-static OsTimerPtr dmxSyncTimer;
-static int dmxSyncPending;
-
-static void dmxDoSync(DMXScreenInfo *dmxScreen)
-{
- dmxScreen->needsSync = FALSE;
-
- if (!dmxScreen->beDisplay)
- return; /* FIXME: Is this correct behavior for sync stats? */
-
- if (!dmxStatInterval) {
- XSync(dmxScreen->beDisplay, False);
- } else {
- struct timeval start, stop;
-
- gettimeofday(&start, 0);
- XSync(dmxScreen->beDisplay, False);
- gettimeofday(&stop, 0);
- dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
- }
-}
-
-static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
-{
- int i;
-
- if (dmxSyncPending) {
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- if (dmxScreen->needsSync) dmxDoSync(dmxScreen);
- }
- }
- dmxSyncPending = 0;
- return 0; /* Do not place on queue again */
-}
-
-static void dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout,
- pointer pReadMask)
-{
- TimerForce(dmxSyncTimer);
-}
-
-static void dmxSyncWakeupHandler(pointer blockData, int result,
- pointer pReadMask)
-{
-}
-
-/** Request the XSync() batching optimization with the specified \a
- * interval (in mS). If the \a interval is 0, 100mS is used. If the \a
- * interval is less than 0, then the XSync() batching optimization is
- * not requested (e.g., so the -syncbatch -1 command line option can
- * turn off the default 100mS XSync() batching).
- *
- * Note that the parameter to this routine is a string, since it will
- * usually be called from #ddxProcessArgument in \a dmxinit.c */
-void dmxSyncActivate(const char *interval)
-{
- dmxSyncInterval = (interval ? atoi(interval) : 100);
-
- if (dmxSyncInterval < 0) dmxSyncInterval = 0;
-}
-
-/** Initialize the XSync() batching optimization, but only if
- * #dmxSyncActivate was last called with a non-negative value. */
-void dmxSyncInit(void)
-{
- if (dmxSyncInterval) {
- RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
- dmxSyncWakeupHandler,
- NULL);
- dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
- dmxSyncInterval);
- } else {
- dmxLog(dmxInfo, "XSync batching disabled\n");
- }
-}
-
-/** Request an XSync() to the display used by \a dmxScreen. If \a now
- * is TRUE, call XSync() immediately instead of waiting for the next
- * XSync() batching point. Note that if XSync() batching was deselected
- * with #dmxSyncActivate() before #dmxSyncInit() was called, then no
- * XSync() batching is performed and this function always calles XSync()
- * immediately.
- *
- * (Note that this function uses TimerSet but works correctly in the
- * face of a server generation. See the source for details.)
- *
- * If \a dmxScreen is \a NULL, then all pending syncs will be flushed
- * immediately.
- */
-void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
-{
- static unsigned long dmxGeneration = 0;
-
- if (dmxSyncInterval) {
- if (dmxGeneration != serverGeneration) {
- /* Server generation does a TimerInit, which frees all
- * timers. So, at this point dmxSyncTimer is either:
- * 1) NULL, iff dmxGeneration == 0,
- * 2) freed, if it was on a queue (dmxSyncPending != 0), or
- * 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
- */
- if (dmxSyncTimer && !dmxSyncPending) free(dmxSyncTimer);
- dmxSyncTimer = NULL;
- now = TRUE;
- dmxGeneration = serverGeneration;
- }
- /* Queue sync */
- if (dmxScreen) {
- dmxScreen->needsSync = TRUE;
- ++dmxSyncPending;
- }
-
- /* Do sync or set time for later */
- if (now || !dmxScreen) {
- if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
- /* At this point, dmxSyncPending == 0 because
- * dmxSyncCallback must have been called. */
- if (dmxSyncPending)
- dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
- dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
- } else {
- dmxScreen->needsSync = TRUE;
- if (dmxSyncPending == 1)
- dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
- dmxSyncCallback, NULL);
- }
- } else {
- /* If dmxSyncInterval is not being used,
- * then all the backends are already
- * up-to-date. */
- if (dmxScreen) dmxDoSync(dmxScreen);
- }
-}
+/*
+ * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ *
+ * The DMX server code is written to call #dmxSync() whenever an XSync()
+ * might be necessary. However, since XSync() requires a two way
+ * communication with the other X server, eliminating unnecessary
+ * XSync() calls is a key performance optimization. Support for this
+ * optimization is provided here. Statistics about XSync() calls and
+ * latency are gathered in \a dmxstat.c.
+ *
+ * During the initial conversion from calling XSync() immediately to the
+ * XSync() batching method implemented in this file, it was noted that,
+ * out of more than 300 \a x11perf tests, 8 tests became more than 100
+ * times faster, with 68 more than 50X faster, 114 more than 10X faster,
+ * and 181 more than 2X faster. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxstat.h"
+#include "dmxlog.h"
+#include <sys/time.h>
+
+static int dmxSyncInterval = 100; /* Default interval in milliseconds */
+static OsTimerPtr dmxSyncTimer;
+static int dmxSyncPending;
+
+static void
+dmxDoSync(DMXScreenInfo * dmxScreen)
+{
+ dmxScreen->needsSync = FALSE;
+
+ if (!dmxScreen->beDisplay)
+ return; /* FIXME: Is this correct behavior for sync stats? */
+
+ if (!dmxStatInterval) {
+ XSync(dmxScreen->beDisplay, False);
+ }
+ else {
+ struct timeval start, stop;
+
+ gettimeofday(&start, 0);
+ XSync(dmxScreen->beDisplay, False);
+ gettimeofday(&stop, 0);
+ dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
+ }
+}
+
+static CARD32
+dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+ int i;
+
+ if (dmxSyncPending) {
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+
+ if (dmxScreen->needsSync)
+ dmxDoSync(dmxScreen);
+ }
+ }
+ dmxSyncPending = 0;
+ return 0; /* Do not place on queue again */
+}
+
+static void
+dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadMask)
+{
+ TimerForce(dmxSyncTimer);
+}
+
+static void
+dmxSyncWakeupHandler(pointer blockData, int result, pointer pReadMask)
+{
+}
+
+/** Request the XSync() batching optimization with the specified \a
+ * interval (in mS). If the \a interval is 0, 100mS is used. If the \a
+ * interval is less than 0, then the XSync() batching optimization is
+ * not requested (e.g., so the -syncbatch -1 command line option can
+ * turn off the default 100mS XSync() batching).
+ *
+ * Note that the parameter to this routine is a string, since it will
+ * usually be called from #ddxProcessArgument in \a dmxinit.c */
+void
+dmxSyncActivate(const char *interval)
+{
+ dmxSyncInterval = (interval ? atoi(interval) : 100);
+
+ if (dmxSyncInterval < 0)
+ dmxSyncInterval = 0;
+}
+
+/** Initialize the XSync() batching optimization, but only if
+ * #dmxSyncActivate was last called with a non-negative value. */
+void
+dmxSyncInit(void)
+{
+ if (dmxSyncInterval) {
+ RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
+ dmxSyncWakeupHandler, NULL);
+ dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
+ dmxSyncInterval);
+ }
+ else {
+ dmxLog(dmxInfo, "XSync batching disabled\n");
+ }
+}
+
+/** Request an XSync() to the display used by \a dmxScreen. If \a now
+ * is TRUE, call XSync() immediately instead of waiting for the next
+ * XSync() batching point. Note that if XSync() batching was deselected
+ * with #dmxSyncActivate() before #dmxSyncInit() was called, then no
+ * XSync() batching is performed and this function always calles XSync()
+ * immediately.
+ *
+ * (Note that this function uses TimerSet but works correctly in the
+ * face of a server generation. See the source for details.)
+ *
+ * If \a dmxScreen is \a NULL, then all pending syncs will be flushed
+ * immediately.
+ */
+void
+dmxSync(DMXScreenInfo * dmxScreen, Bool now)
+{
+ static unsigned long dmxGeneration = 0;
+
+ if (dmxSyncInterval) {
+ if (dmxGeneration != serverGeneration) {
+ /* Server generation does a TimerInit, which frees all
+ * timers. So, at this point dmxSyncTimer is either:
+ * 1) NULL, iff dmxGeneration == 0,
+ * 2) freed, if it was on a queue (dmxSyncPending != 0), or
+ * 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
+ */
+ if (dmxSyncTimer && !dmxSyncPending)
+ free(dmxSyncTimer);
+ dmxSyncTimer = NULL;
+ now = TRUE;
+ dmxGeneration = serverGeneration;
+ }
+ /* Queue sync */
+ if (dmxScreen) {
+ dmxScreen->needsSync = TRUE;
+ ++dmxSyncPending;
+ }
+
+ /* Do sync or set time for later */
+ if (now || !dmxScreen) {
+ if (!TimerForce(dmxSyncTimer))
+ dmxSyncCallback(NULL, 0, NULL);
+ /* At this point, dmxSyncPending == 0 because
+ * dmxSyncCallback must have been called. */
+ if (dmxSyncPending)
+ dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
+ dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
+ }
+ else {
+ dmxScreen->needsSync = TRUE;
+ if (dmxSyncPending == 1)
+ dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
+ dmxSyncCallback, NULL);
+ }
+ }
+ else {
+ /* If dmxSyncInterval is not being used,
+ * then all the backends are already
+ * up-to-date. */
+ if (dmxScreen)
+ dmxDoSync(dmxScreen);
+ }
+}