#include "reqstats.h"
#ifdef LBXREQSTATS
#include <X11/Xfuncs.h>
#include <X11/Xproto.h>
#define _XLBX_SERVER_
#include "XLbx.h"
#include "lbx_zlib.h"
#include <signal.h>
#include <stdio.h>
#define LBX_CODE 136
extern unsigned long stream_in_compressed;
extern unsigned long stream_in_plain;
extern unsigned long stream_in_packet_header_bytes;
extern unsigned long stream_in_uncompressed_bytes;
unsigned long check_sum_in_compressed;
unsigned long check_sum_in_plain;
int unknown_extension_bytes = 0;
struct ReqStats CoreRequestStats[128];
struct ReqStats LbxRequestStats[LbxNumberReqs];
static void LbxPrintReqStats (int);
char *X_ReqNames[128] = {
0,
"CreateWindow",
"ChangeWindowAttributes",
"GetWindowAttributes",
"DestroyWindow",
"DestroySubwindows",
"ChangeSaveSet",
"ReparentWindow",
"MapWindow",
"MapSubwindows",
"UnmapWindow",
"UnmapSubwindows",
"ConfigureWindow",
"CirculateWindow",
"GetGeometry",
"QueryTree",
"InternAtom",
"GetAtomName",
"ChangeProperty",
"DeleteProperty",
"GetProperty",
"ListProperties",
"SetSelectionOwner",
"GetSelectionOwner",
"ConvertSelection",
"SendEvent",
"GrabPointer",
"UngrabPointer",
"GrabButton",
"UngrabButton",
"ChangeActivePointerGrab",
"GrabKeyboard",
"UngrabKeyboard",
"GrabKey",
"UngrabKey",
"AllowEvents",
"GrabServer",
"UngrabServer",
"QueryPointer",
"GetMotionEvents",
"TranslateCoords",
"WarpPointer",
"SetInputFocus",
"GetInputFocus",
"QueryKeymap",
"OpenFont",
"CloseFont",
"QueryFont",
"QueryTextExtents",
"ListFonts",
"ListFontsWithInfo",
"SetFontPath",
"GetFontPath",
"CreatePixmap",
"FreePixmap",
"CreateGC",
"ChangeGC",
"CopyGC",
"SetDashes",
"SetClipRectangles",
"FreeGC",
"ClearArea",
"CopyArea",
"CopyPlane",
"PolyPoint",
"PolyLine",
"PolySegment",
"PolyRectangle",
"PolyArc",
"FillPoly",
"PolyFillRectangle",
"PolyFillArc",
"PutImage",
"GetImage",
"PolyText8",
"PolyText16",
"ImageText8",
"ImageText16",
"CreateColormap",
"FreeColormap",
"CopyColormapAndFree",
"InstallColormap",
"UninstallColormap",
"ListInstalledColormaps",
"AllocColor",
"AllocNamedColor",
"AllocColorCells",
"AllocColorPlanes",
"FreeColors",
"StoreColors",
"StoreNamedColor",
"QueryColors",
"LookupColor",
"CreateCursor",
"CreateGlyphCursor",
"FreeCursor",
"RecolorCursor",
"QueryBestSize",
"QueryExtension",
"ListExtensions",
"ChangeKeyboardMapping",
"GetKeyboardMapping",
"ChangeKeyboardControl",
"GetKeyboardControl",
"Bell",
"ChangePointerControl",
"GetPointerControl",
"SetScreenSaver",
"GetScreenSaver",
"ChangeHosts",
"ListHosts",
"SetAccessControl",
"SetCloseDownMode",
"KillClient",
"RotateProperties",
"ForceScreenSaver",
"SetPointerMapping",
"GetPointerMapping",
"SetModifierMapping",
"GetModifierMapping",
0,
0,
0,
0,
0,
0,
0,
"NoOperation"
};
char *LBX_ReqNames[LbxNumberReqs] = {
"LbxQueryVersion",
"LbxStartProxy",
"LbxStopProxy",
"LbxSwitch",
"LbxNewClient",
"LbxCloseClient",
"LbxModifySequence",
"LbxAllowMotion",
"LbxIncrementPixel",
"LbxDelta",
"LbxGetModifierMapping",
"LbxQueryTag",
"LbxInvalidateTag",
"LbxPolyPoint",
"LbxPolyLine",
"LbxPolySegment",
"LbxPolyRectangle",
"LbxPolyArc",
"LbxFillPoly",
"LbxPolyFillRectangle",
"LbxPolyFillArc",
"LbxGetKeyboardMapping",
"LbxQueryFont",
"LbxChangeProperty",
"LbxGetProperty",
"LbxTagData",
"LbxCopyArea",
"LbxCopyPlane",
"LbxPolyText8",
"LbxPolyText16",
"LbxImageText8",
"LbxImageText16",
"LbxQueryExtension",
"LbxPutImage",
"LbxGetImage",
"LbxBeginLargeRequest",
"LbxLargeRequestData",
"LbxEndLargeRequest"
};
void
InitLbxReqStats (void)
{
bzero (CoreRequestStats, 128 * sizeof (struct ReqStats));
bzero (LbxRequestStats, LbxNumberReqs * sizeof (struct ReqStats));
signal (SIGUSR1, LbxPrintReqStats);
}
static void
PrintStatsTable (struct ReqStats *table,
int count,
char **reqNames)
{
int i;
fprintf (stderr, "U = uncompressed bytes\n");
fprintf (stderr, "C = compressed bytes\n");
fprintf (stderr, "%%C = percent compression\n");
fprintf (stderr, "%%T = percent of total bytes in stream\n");
fprintf (stderr, "\n");
fprintf (stderr, "%-25s\tCount\tU\tC\t%%C\t\t%%T\n", "Request");
fprintf (stderr, "-------------------------------------------------------------------------------\n");
for (i = 0; i < count; i++)
{
float compRatio, percentTot;
if (table[i].uncomp_bytes == 0)
compRatio = 0.0;
else
compRatio = 100.0 * (1.0 - ((float) table[i].comp_bytes /
(float) table[i].uncomp_bytes));
if (stream_in_compressed - stream_in_packet_header_bytes == 0)
percentTot = 0.0;
else
percentTot = 100.0 * (float) table[i].comp_bytes /
(float) (stream_in_compressed -
stream_in_packet_header_bytes);
if (reqNames[i])
fprintf (stderr, "%-25s\t%d\t%d\t%d\t%.3f\t\t%.3f\n",
reqNames[i],
table[i].count,
table[i].uncomp_bytes,
table[i].comp_bytes,
compRatio,
percentTot);
check_sum_in_plain += table[i].uncomp_bytes;
check_sum_in_compressed += table[i].comp_bytes;
}
}
static void
PrintDeltaStats (struct ReqStats *table,
int count,
char **reqNames)
{
int i;
for (i = 0; i < count; i++)
{
if (table[i].delta_count && reqNames[i])
fprintf (stderr, "%-25s\t%d\t%d\t%d\n",
reqNames[i],
table[i].delta_count,
table[i].pre_delta_bytes,
table[i].post_delta_bytes);
}
}
static void
LbxPrintReqStats (int dummy)
{
unsigned long total;
check_sum_in_plain = 0;
check_sum_in_compressed = 0;
fprintf (stderr, "\n\n");
fprintf (stderr, "Core X requests\n\n");
PrintStatsTable (CoreRequestStats, 128, X_ReqNames);
fprintf (stderr, "\n\n");
fprintf (stderr, "LBX requests\n\n");
PrintStatsTable (LbxRequestStats, LbxNumberReqs, LBX_ReqNames);
fprintf (stderr, "\n\n\n");
fprintf (stderr, "The following requests were delta compressed:\n");
fprintf (stderr, "\n");
fprintf (stderr, "Pre = pre delta bytes\n");
fprintf (stderr, "Post = post delta bytes\n");
fprintf (stderr, "\n");
fprintf (stderr, "%-25s\tCount\tPre\tPost\n", "Request");
fprintf (stderr, "-------------------------------------------------------------------------------\n");
PrintDeltaStats (CoreRequestStats, 128, X_ReqNames);
PrintDeltaStats (LbxRequestStats, LbxNumberReqs, LBX_ReqNames);
fprintf (stderr, "\n\n\n");
fprintf (stderr, "overall stream compression = %f %%\n",
(check_sum_in_plain == 0) ? 0.0 :
(100.0 * (1.0 - ((float) check_sum_in_compressed /
(float) check_sum_in_plain))));
fprintf (stderr, "\n\n\n");
total = check_sum_in_plain + unknown_extension_bytes +
stream_in_uncompressed_bytes;
if (total == stream_in_plain)
fprintf (stderr, "Internal checksum succeeded!!!\n");
else
{
fprintf (stderr, "Internal checksum failed!!!\n");
fprintf (stderr, "actual checksum = %d\n", stream_in_plain);
fprintf (stderr, "computed checksum = %d\n", total);
}
fprintf (stderr, "\n\n");
}
void
do_decompress_with_stats (struct compress_private *priv)
{
int incount = priv->cp_inputbufend - priv->cp_inputbuf;
priv->stream.next_in = priv->cp_inputbuf;
priv->stream.next_out = priv->cp_outputbuf;
priv->stream.avail_out = priv->cp_outputbufend - priv->cp_outputbuf;
while (incount > 0)
{
char *save_out = (char *) priv->stream.next_out;
int outcount, outconsumed;
priv->stream.avail_in = 1;
priv->z_err = inflate (&(priv->stream), Z_NO_FLUSH);
priv->need_flush_decompress = (priv->stream.avail_out == 0 );
priv->req_compbytes_read++;
outcount = (char *) priv->stream.next_out - save_out;
priv->req_uncompbytes_read += outcount;
while (outcount > 0)
{
if (priv->req_length == -1 && priv->x_header_bytes_read < 4)
{
int have = MIN (outcount, (4 - priv->x_header_bytes_read));
memcpy (priv->x_header_buf + priv->x_header_bytes_read,
save_out, have);
priv->x_header_bytes_read += have;
if (priv->x_header_bytes_read < 4 && ((outcount - have) == 0))
break;
}
if (priv->req_length == -1 && priv->x_header_bytes_read == 4)
{
xReq *req = (xReq *) priv->x_header_buf;
priv->req_length = req->length << 2;
priv->x_req_code = req->reqType;
if (priv->x_req_code == LBX_CODE)
priv->lbx_req_code = req->data;
}
if (priv->req_length != -1)
{
if (priv->req_uncompbytes_read < priv->req_length)
break;
else
{
if (priv->x_req_code == LBX_CODE)
{
struct ReqStats *reqStat =
&LbxRequestStats[priv->lbx_req_code];
reqStat->count++;
reqStat->comp_bytes += priv->req_compbytes_read;
reqStat->uncomp_bytes += priv->req_length;
#ifdef LBXREQLOG
fprintf (stderr,
"LBX opcode = %d, real len = %d, comp len = %d\n",
priv->lbx_req_code, priv->req_length,
priv->req_compbytes_read);
#endif
}
else if (priv->x_req_code < 128)
{
struct ReqStats *reqStat =
&CoreRequestStats[priv->x_req_code];
reqStat->count++;
reqStat->comp_bytes += priv->req_compbytes_read;
reqStat->uncomp_bytes += priv->req_length;
#ifdef LBXREQLOG
fprintf (stderr,
"X opcode = %d, real len = %d, comp len = %d\n",
priv->x_req_code, priv->req_length,
priv->req_compbytes_read);
#endif
}
else
{
#ifdef LBXREQLOG
fprintf (stderr,
"Unknown opcode = %d, real len = %d, comp len = %d\n",
priv->x_req_code, priv->req_length,
priv->req_compbytes_read);
#endif
unknown_extension_bytes += priv->req_length;
}
priv->req_uncompbytes_read -= priv->req_length;
if (priv->req_uncompbytes_read > 0)
{
priv->req_compbytes_read = 1;
save_out += (outcount - priv->req_uncompbytes_read);
outcount = priv->req_uncompbytes_read;
}
else
{
priv->req_compbytes_read = 0;
outcount = 0;
}
priv->req_length = -1;
priv->x_header_bytes_read = 0;
}
}
}
incount--;
if (priv->stream.avail_out == 0)
break;
}
priv->cp_inputbuf = priv->stream.next_in;
priv->cp_outputbuf = priv->stream.next_out;
}
#else
void
InitLbxReqStats()
{}
#endif