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 | |||
36 | AM_CONFIG_HEADER(config.h) | 36 | AM_CONFIG_HEADER(config.h) |
37 | 37 | ||
38 | # Checks for pkg-config packages | 38 | # Checks for pkg-config packages |
39 | PKG_CHECK_MODULES(XDPYINFO, xext x11 xtst) | 39 | PKG_CHECK_MODULES(XDPYINFO, xext x11 xtst x11-xcb xcb) |
40 | 40 | ||
41 | # This is used below to allow <X11/Xlib.h> to be found | 41 | # This is used below to allow <X11/Xlib.h> to be found |
42 | PKG_CHECK_MODULES(DPY_X11, x11) | 42 | PKG_CHECK_MODULES(DPY_X11, x11) |
@@ -82,6 +82,7 @@ in this Software without prior written authorization from The Open Group. | |||
82 | 82 | ||
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | #include <X11/Xlib-xcb.h> | ||
85 | #include <X11/Xlib.h> | 86 | #include <X11/Xlib.h> |
86 | #include <X11/Xutil.h> | 87 | #include <X11/Xutil.h> |
87 | #ifdef MULTIBUFFER | 88 | #ifdef MULTIBUFFER |
@@ -170,22 +171,53 @@ print_extension_info(Display *dpy) | |||
170 | printf ("number of extensions: %d\n", n); | 171 | printf ("number of extensions: %d\n", n); |
171 | 172 | ||
172 | if (extlist) { | 173 | if (extlist) { |
173 | register int i; | 174 | int i; |
174 | int opcode, event, error; | ||
175 | 175 | ||
176 | qsort(extlist, n, sizeof(char *), StrCmp); | 176 | qsort(extlist, n, sizeof(char *), StrCmp); |
177 | for (i = 0; i < n; i++) { | 177 | |
178 | if (!queryExtensions) { | 178 | if (!queryExtensions) { |
179 | for (i = 0; i < n; i++) { | ||
179 | printf (" %s\n", extlist[i]); | 180 | printf (" %s\n", extlist[i]); |
180 | continue; | ||
181 | } | 181 | } |
182 | XQueryExtension(dpy, extlist[i], &opcode, &event, &error); | 182 | } else { |
183 | printf (" %s (opcode: %d", extlist[i], opcode); | 183 | xcb_connection_t *xcb_conn = XGetXCBConnection (dpy); |
184 | if (event) | 184 | xcb_query_extension_cookie_t *qe_cookies; |
185 | printf (", base event: %d", event); | 185 | |
186 | if (error) | 186 | qe_cookies = calloc(n, sizeof(xcb_query_extension_cookie_t)); |
187 | printf (", base error: %d", error); | 187 | if (!qe_cookies) { |
188 | printf(")\n"); | 188 | perror ("calloc failed to allocate memory for extensions"); |
189 | return; | ||
190 | } | ||
191 | |||
192 | /* | ||
193 | * Generate all extension queries at once, so they can be | ||
194 | * sent to the xserver in a single batch | ||
195 | */ | ||
196 | for (i = 0; i < n; i++) { | ||
197 | qe_cookies[i] = xcb_query_extension (xcb_conn, | ||
198 | strlen(extlist[i]), | ||
199 | extlist[i]); | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * Start processing replies as they come in. | ||
204 | * The first call will flush the queue to the server, then | ||
205 | * each one will wait, if needed, for its reply. | ||
206 | */ | ||
207 | for (i = 0; i < n; i++) { | ||
208 | xcb_query_extension_reply_t *rep | ||
209 | = xcb_query_extension_reply(xcb_conn, qe_cookies[i], NULL); | ||
210 | |||
211 | printf (" %s (opcode: %d", extlist[i], rep->major_opcode); | ||
212 | if (rep->first_event) | ||
213 | printf (", base event: %d", rep->first_event); | ||
214 | if (rep->first_error) | ||
215 | printf (", base error: %d", rep->first_error); | ||
216 | printf (")\n"); | ||
217 | |||
218 | free (rep); | ||
219 | } | ||
220 | free (qe_cookies); | ||
189 | } | 221 | } |
190 | /* do not free, Xlib can depend on contents being unaltered */ | 222 | /* do not free, Xlib can depend on contents being unaltered */ |
191 | /* XFreeExtensionList (extlist); */ | 223 | /* XFreeExtensionList (extlist); */ |