From: Alan Coopersmith Date: Sun, 3 Oct 2010 18:47:07 +0000 (-0700) Subject: Use xcb for -queryExt instead of a round-trip per extension X-Git-Tag: xdpyinfo-1.3.0~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=072fc46b2af370e78fa53426626ca3c33b74bdf2;p=platform%2Fupstream%2Fxdpyinfo.git Use xcb for -queryExt instead of a round-trip per extension On a system with 30 extensions listed by xdpyinfo, truss -c reports this saves quite a few system calls by batching the QueryExtension requests instead of a round-trip for each one: Xlib xcb writev 40 11 poll 80 22 recv 117 29 total (*) 464 296 (*) total includes all system calls, including many not shown since their count did not change significantly. There was one additional set of open/mmap/close etc. for loading the added libX11-xcb library. Over a tcp connection, this reduced both the number of packets, and due to tcp packet header overhead, the overall amount of data: Xlib xcb TCP packets 93 35 TCP bytes 11554 7726 Signed-off-by: Alan Coopersmith Reviewed-by: Jamey Sharp --- diff --git a/configure.ac b/configure.ac index 48ae434..47a1246 100644 --- a/configure.ac +++ b/configure.ac @@ -36,7 +36,7 @@ XORG_DEFAULT_OPTIONS AM_CONFIG_HEADER(config.h) # Checks for pkg-config packages -PKG_CHECK_MODULES(XDPYINFO, xext x11 xtst) +PKG_CHECK_MODULES(XDPYINFO, xext x11 xtst x11-xcb xcb) # This is used below to allow to be found PKG_CHECK_MODULES(DPY_X11, x11) diff --git a/xdpyinfo.c b/xdpyinfo.c index db4a438..017738f 100644 --- a/xdpyinfo.c +++ b/xdpyinfo.c @@ -82,6 +82,7 @@ in this Software without prior written authorization from The Open Group. #endif +#include #include #include #ifdef MULTIBUFFER @@ -170,22 +171,53 @@ print_extension_info(Display *dpy) printf ("number of extensions: %d\n", n); if (extlist) { - register int i; - int opcode, event, error; + int i; qsort(extlist, n, sizeof(char *), StrCmp); - for (i = 0; i < n; i++) { - if (!queryExtensions) { + + if (!queryExtensions) { + for (i = 0; i < n; i++) { printf (" %s\n", extlist[i]); - continue; } - XQueryExtension(dpy, extlist[i], &opcode, &event, &error); - printf (" %s (opcode: %d", extlist[i], opcode); - if (event) - printf (", base event: %d", event); - if (error) - printf (", base error: %d", error); - printf(")\n"); + } else { + xcb_connection_t *xcb_conn = XGetXCBConnection (dpy); + xcb_query_extension_cookie_t *qe_cookies; + + qe_cookies = calloc(n, sizeof(xcb_query_extension_cookie_t)); + if (!qe_cookies) { + perror ("calloc failed to allocate memory for extensions"); + return; + } + + /* + * Generate all extension queries at once, so they can be + * sent to the xserver in a single batch + */ + for (i = 0; i < n; i++) { + qe_cookies[i] = xcb_query_extension (xcb_conn, + strlen(extlist[i]), + extlist[i]); + } + + /* + * Start processing replies as they come in. + * The first call will flush the queue to the server, then + * each one will wait, if needed, for its reply. + */ + for (i = 0; i < n; i++) { + xcb_query_extension_reply_t *rep + = xcb_query_extension_reply(xcb_conn, qe_cookies[i], NULL); + + printf (" %s (opcode: %d", extlist[i], rep->major_opcode); + if (rep->first_event) + printf (", base event: %d", rep->first_event); + if (rep->first_error) + printf (", base error: %d", rep->first_error); + printf (")\n"); + + free (rep); + } + free (qe_cookies); } /* do not free, Xlib can depend on contents being unaltered */ /* XFreeExtensionList (extlist); */