diff options
author | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-06-28 22:07:26 +0000 |
commit | 3562e78743202e43aec8727005182a2558117eca (patch) | |
tree | 8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/hw/dmx/dmxstat.c | |
download | vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2 vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip |
Checked in the following released items:
xkeyboard-config-1.4.tar.gz
ttf-bitstream-vera-1.10.tar.gz
font-alias-1.0.1.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sun-misc-1.0.0.tar.gz
font-sony-misc-1.0.0.tar.gz
font-schumacher-misc-1.0.0.tar.gz
font-mutt-misc-1.0.0.tar.gz
font-misc-misc-1.0.0.tar.gz
font-misc-meltho-1.0.0.tar.gz
font-micro-misc-1.0.0.tar.gz
font-jis-misc-1.0.0.tar.gz
font-isas-misc-1.0.0.tar.gz
font-dec-misc-1.0.0.tar.gz
font-daewoo-misc-1.0.0.tar.gz
font-cursor-misc-1.0.0.tar.gz
font-arabic-misc-1.0.0.tar.gz
font-winitzki-cyrillic-1.0.0.tar.gz
font-misc-cyrillic-1.0.0.tar.gz
font-cronyx-cyrillic-1.0.0.tar.gz
font-screen-cyrillic-1.0.1.tar.gz
font-xfree86-type1-1.0.1.tar.gz
font-adobe-utopia-type1-1.0.1.tar.gz
font-ibm-type1-1.0.0.tar.gz
font-bitstream-type1-1.0.0.tar.gz
font-bitstream-speedo-1.0.0.tar.gz
font-bh-ttf-1.0.0.tar.gz
font-bh-type1-1.0.0.tar.gz
font-bitstream-100dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz
font-bh-100dpi-1.0.0.tar.gz
font-adobe-utopia-100dpi-1.0.1.tar.gz
font-adobe-100dpi-1.0.0.tar.gz
font-util-1.0.1.tar.gz
font-bitstream-75dpi-1.0.0.tar.gz
font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz
font-adobe-utopia-75dpi-1.0.1.tar.gz
font-bh-75dpi-1.0.0.tar.gz
bdftopcf-1.0.1.tar.gz
font-adobe-75dpi-1.0.0.tar.gz
mkfontscale-1.0.6.tar.gz
openssl-0.9.8k.tar.gz
bigreqsproto-1.0.2.tar.gz
xtrans-1.2.2.tar.gz
resourceproto-1.0.2.tar.gz
inputproto-1.4.4.tar.gz
compositeproto-0.4.tar.gz
damageproto-1.1.0.tar.gz
zlib-1.2.3.tar.gz
xkbcomp-1.0.5.tar.gz
freetype-2.3.9.tar.gz
pthreads-w32-2-8-0-release.tar.gz
pixman-0.12.0.tar.gz
kbproto-1.0.3.tar.gz
evieext-1.0.2.tar.gz
fixesproto-4.0.tar.gz
recordproto-1.13.2.tar.gz
randrproto-1.2.2.tar.gz
scrnsaverproto-1.1.0.tar.gz
renderproto-0.9.3.tar.gz
xcmiscproto-1.1.2.tar.gz
fontsproto-2.0.2.tar.gz
xextproto-7.0.3.tar.gz
xproto-7.0.14.tar.gz
libXdmcp-1.0.2.tar.gz
libxkbfile-1.0.5.tar.gz
libfontenc-1.0.4.tar.gz
libXfont-1.3.4.tar.gz
libX11-1.1.5.tar.gz
libXau-1.0.4.tar.gz
libxcb-1.1.tar.gz
xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/hw/dmx/dmxstat.c')
-rw-r--r-- | xorg-server/hw/dmx/dmxstat.c | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/xorg-server/hw/dmx/dmxstat.c b/xorg-server/hw/dmx/dmxstat.c new file mode 100644 index 000000000..a89c69eae --- /dev/null +++ b/xorg-server/hw/dmx/dmxstat.c @@ -0,0 +1,222 @@ +/* + * Copyright 2002, 2003 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 in #dmxsync.c. This file provides routines + * that evaluate this optimization by counting the number of XSync() + * calls and monitoring their latency. This functionality can be turned + * on using the -stat command-line parameter. */ + +#ifdef HAVE_DMX_CONFIG_H +#include <dmx-config.h> +#endif + +#include "dmx.h" +#include "dmxstat.h" +#include "dmxlog.h" +#include <X11/Xos.h> /* For sys/time.h */ + +/** Used to compute a running average of value. */ +typedef struct _DMXStatAvg { + int pos; + int count; + unsigned long value[DMX_STAT_LENGTH]; +} DMXStatAvg; + +/** Statistical information about XSync calls. */ +struct _DMXStatInfo { + unsigned long syncCount; + unsigned long oldSyncCount; + + DMXStatAvg usec; + DMXStatAvg pending; + + unsigned long bins[DMX_STAT_BINS]; +}; + +/* Interval in mS between statistic message log entries. */ + int dmxStatInterval; +static int dmxStatDisplays; +static OsTimerPtr dmxStatTimer; + +/** Return the number of microseconds as an unsigned long. + * Unfortunately, this is only useful for intervals < about 4 sec. */ +static unsigned long usec(struct timeval *stop, struct timeval *start) +{ + return (stop->tv_sec - start->tv_sec) * 1000000 + + stop->tv_usec - start->tv_usec; +} + +static unsigned long avg(DMXStatAvg *data, unsigned long *max) +{ + unsigned long sum; + int i; + + *max = 0; + if (!data->count) return 0; + + for (i = 0, sum = 0; i < data->count; i++) { + if (data->value[i] > *max) *max = data->value[i]; + sum += data->value[i]; + } + return sum / data->count; +} + +/** Turn on XSync statistic gathering and printing. Print every \a + * interval seconds, with lines for the first \a displays. If \a + * interval is NULL, 1 will be used. If \a displays is NULL, 0 will be + * used (meaning a line for every display will be printed). Note that + * this function takes string arguments because it will usually be + * called from #ddxProcessArgument in #dmxinit.c. */ +void dmxStatActivate(const char *interval, const char *displays) +{ + dmxStatInterval = (interval ? atoi(interval) : 1) * 1000; + dmxStatDisplays = (displays ? atoi(displays) : 0); + + if (dmxStatInterval < 1000) dmxStatInterval = 1000; + if (dmxStatDisplays < 0) dmxStatDisplays = 0; +} + +/** Allocate a \a DMXStatInfo structure. */ +DMXStatInfo *dmxStatAlloc(void) +{ + DMXStatInfo *pt = malloc(sizeof(*pt)); + memset(pt, 0, sizeof(*pt)); + return pt; +} + +/** Free the memory used by a \a DMXStatInfo structure. */ +void dmxStatFree(DMXStatInfo *pt) +{ + if (pt) free(pt); +} + +static void dmxStatValue(DMXStatAvg *data, unsigned long value) +{ + if (data->count != DMX_STAT_LENGTH) ++data->count; + if (data->pos >= DMX_STAT_LENGTH-1) data->pos = 0; + data->value[data->pos++] = value; +} + +/** Note that a XSync() was just done on \a dmxScreen with the \a start + * and \a stop times (from gettimeofday()) and the number of + * pending-but-not-yet-processed XSync requests. This routine is called + * from #dmxDoSync in #dmxsync.c */ +void dmxStatSync(DMXScreenInfo *dmxScreen, + struct timeval *stop, struct timeval *start, + unsigned long pending) +{ + DMXStatInfo *s = dmxScreen->stat; + unsigned long elapsed = usec(stop, start); + unsigned long thresh; + int i; + + ++s->syncCount; + dmxStatValue(&s->usec, elapsed); + dmxStatValue(&s->pending, pending); + + for (i = 0, thresh = DMX_STAT_BIN0; i < DMX_STAT_BINS-1; i++) { + if (elapsed < thresh) { + ++s->bins[i]; + break; + } + thresh *= DMX_STAT_BINMULT; + } + if (i == DMX_STAT_BINS-1) ++s->bins[i]; +} + +/* Actually do the work of printing out the human-readable message. */ +static CARD32 dmxStatCallback(OsTimerPtr timer, CARD32 t, pointer arg) +{ + int i, j; + static int header = 0; + int limit = dmxNumScreens; + + if (!dmxNumScreens) { + header = 0; + return DMX_STAT_INTERVAL; + } + + if (!header++ || !(header % 10)) { + dmxLog(dmxDebug, + " S SyncCount Sync/s avSync mxSync avPend mxPend | " + "<10ms <1s >1s\n"); + } + + if (dmxStatDisplays && dmxStatDisplays < limit) limit = dmxStatDisplays; + for (i = 0; i < limit; i++) { + DMXScreenInfo *dmxScreen = &dmxScreens[i]; + DMXStatInfo *s = dmxScreen->stat; + unsigned long aSync, mSync; + unsigned long aPend, mPend; + + if (!s) continue; + + aSync = avg(&s->usec, &mSync); + aPend = avg(&s->pending, &mPend); + dmxLog(dmxDebug, "%2d %9lu %7lu %6lu %6lu %6lu %6lu |", + i, /* S */ + s->syncCount, /* SyncCount */ + (s->syncCount + - s->oldSyncCount) * 1000 / dmxStatInterval, /* Sync/s */ + aSync, /* us/Sync */ + mSync, /* max/Sync */ + aPend, /* avgPend */ + mPend); /* maxPend */ + for (j = 0; j < DMX_STAT_BINS; j++) + dmxLogCont(dmxDebug, " %5lu", s->bins[j]); + dmxLogCont(dmxDebug, "\n"); + + /* Reset/clear */ + s->oldSyncCount = s->syncCount; + for (j = 0; j < DMX_STAT_BINS; j++) s->bins[j] = 0; + } + return DMX_STAT_INTERVAL; /* Place on queue again */ +} + +/** Try to initialize the statistic gathering and printing routines. + * Initialization only takes place if #dmxStatActivate has already been + * called. We don't need the same generation protection that we used in + * dmxSyncInit because our timer is always on a queue -- hence, server + * generation will always free it. */ +void dmxStatInit(void) +{ + if (dmxStatInterval) + dmxStatTimer = TimerSet(NULL, 0, + dmxStatInterval, dmxStatCallback, NULL); +} |