diff options
author | Alan Coopersmith <alan.coopersmith@oracle.com> | 2010-10-03 11:47:07 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2010-10-04 08:14:48 -0700 |
commit | 072fc46b2af370e78fa53426626ca3c33b74bdf2 (patch) | |
tree | 575a85d3e1451e604f81c3292102356b37019c3e | |
parent | 30bc4b0ada659809c64f6a8292cbde3166267e8d (diff) |
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 <alan.coopersmith@oracle.com>
Reviewed-by: Jamey Sharp <jamey@minilop.net>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | xdpyinfo.c | 56 |
2 files changed, 45 insertions, 13 deletions
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 <X11/Xlib.h> to be found PKG_CHECK_MODULES(DPY_X11, x11) @@ -82,6 +82,7 @@ in this Software without prior written authorization from The Open Group. #endif +#include <X11/Xlib-xcb.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #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); */ |