[PATCH v2:xdpyinfo] Use xcb for -queryExt instead of a round-trip per extension

Alan Coopersmith alan.coopersmith at oracle.com
Sun Oct 3 14:48:36 PDT 2010


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 at oracle.com>
---

Updated per Jamey's suggestion to not rely on C99's variable length arrays,
to remove unneccesary xcb_flush (with comments added to explain that), and
to show delta in TCP packets/bytes.

 configure.ac |    2 +-
 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)
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 <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); */
-- 
1.5.6.5



More information about the xorg-devel mailing list