[Xcb] [PATCH] Making XCB less of a memory hog

Tilman Sauerbeck tilman at code-monkey.de
Fri May 11 08:16:43 PDT 2007


Hi,
atm, every X request for a protocol extension causes one relocation in
the resulting DSO. This sucks a lot especially for libraries with a
number of requests obviously, eg libxcb-glx.so:

/usr/lib/libxcb-glx.so: 200 relocations, 3 relative (1%), 4 PLT entries, 0 for local syms (0%)

The problem is that every request defines a
  static const xcb_protocol_request_t
that contains a pointer to the global xcb_extension_t.

The latter isn't constant obviously, so you need to compute the address
when you load the library.
Also, this makes it necessary to put the protocol request structures
into read-write sections, since you need to touch at them at load time.

I attached which fixes both of these problems. It removes the extension
pointer from the request struct, so all of the values in that struct are
now known at build time, and the request can be put into read-only
sections of the DSO (so the data can be shared between processes!) and
there's no need for relocation.

For extension requests, the pointer to the xcb_extension_t is now passed
as another argument in xcb_send_request().

So, in short, this patch reduces the memory that XCB eats at runtime,
and it reduces the load time for the libraries.

OTOH, this unfortunately breaks the API.

Another idea to get the benefits of this approach right now is to add
another function, xcb_send_request2() or something, and leave the
current as-is. xcb_send_request2() would just ignore the "ext" field
in xcb_protocol_request_t and take it as an argument instead.

What do you think about the patch in general, and the idea to extend the
API so we can make use of it right now instead of in n years, when we
might be able to break the API?

Regards,
Tilman

-- 
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
-------------- next part --------------
diff --git a/src/c-client.xsl b/src/c-client.xsl
index 24ffe6c..b21f849 100644
--- a/src/c-client.xsl
+++ b/src/c-client.xsl
@@ -721,14 +721,6 @@ authorization from the authors.
     <l>static const xcb_protocol_request_t xcb_req = {</l>
     <indent>
       <l>/* count */ <xsl:value-of select="$num-parts" />,</l>
-      <l>/* ext */ <xsl:choose>
-                     <xsl:when test="$ext">
-                       <xsl:text>&amp;</xsl:text>
-                       <xsl:value-of select="xcb:xcb-prefix()" />
-                       <xsl:text>_id</xsl:text>
-                     </xsl:when>
-                     <xsl:otherwise>0</xsl:otherwise>
-                   </xsl:choose>,</l>
       <l>/* opcode */ <xsl:value-of select="@opcode" />,</l>
       <l>/* isvoid */ <xsl:value-of select="1-boolean(@has-reply)" /></l>
     </indent>
@@ -779,7 +771,15 @@ authorization from the authors.
     --><xsl:choose>
          <xsl:when test="@checked='true'">XCB_REQUEST_CHECKED</xsl:when>
          <xsl:otherwise>0</xsl:otherwise>
-       </xsl:choose>, xcb_parts + 2, &amp;xcb_req);</l>
+       </xsl:choose>, xcb_parts + 2, &amp;xcb_req, <!--
+    --><xsl:choose>
+         <xsl:when test="$ext">
+            <xsl:text>&amp;</xsl:text>
+              <xsl:value-of select="xcb:xcb-prefix()" />
+                <xsl:text>_id</xsl:text>
+              </xsl:when>
+            <xsl:otherwise>NULL</xsl:otherwise>
+          </xsl:choose>);</l>
     <l>return xcb_ret;</l>
   </xsl:template>
 
diff --git a/src/xcb_out.c b/src/xcb_out.c
index caf8ef5..c75fa36 100644
--- a/src/xcb_out.c
+++ b/src/xcb_out.c
@@ -102,7 +102,7 @@ uint32_t xcb_get_maximum_request_length(xcb_connection_t *c)
     return c->out.maximum_request_length.value;
 }
 
-unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req)
+unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *req, xcb_extension_t *ext)
 {
     static const union {
         struct {
@@ -132,9 +132,9 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
         size_t longlen = 0;
         assert(vector[0].iov_len >= 4);
         /* set the major opcode, and the minor opcode for extensions */
-        if(req->ext)
+        if(ext)
         {
-            const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, req->ext);
+            const xcb_query_extension_reply_t *extension = xcb_get_extension_data(c, ext);
             if(!(extension && extension->present))
             {
                 _xcb_conn_shutdown(c);
@@ -181,7 +181,7 @@ unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vect
     /* do we need to work around the X server bug described in glx.xml? */
     /* XXX: GetFBConfigs won't use BIG-REQUESTS in any sane
      * configuration, but that should be handled here anyway. */
-    if(req->ext && !req->isvoid && !strcmp(req->ext->name, "GLX") &&
+    if(ext && !req->isvoid && !strcmp(ext->name, "GLX") &&
             ((req->opcode == 17 && ((uint32_t *) vector[0].iov_base)[1] == 0x10004) ||
              req->opcode == 21))
         workaround = WORKAROUND_GLX_GET_FB_CONFIGS_BUG;
diff --git a/src/xcbext.h b/src/xcbext.h
index 01dd590..1ef2b46 100644
--- a/src/xcbext.h
+++ b/src/xcbext.h
@@ -46,7 +46,6 @@ struct xcb_extension_t {
 
 typedef struct {
     size_t count;
-    xcb_extension_t *ext;
     uint8_t opcode;
     uint8_t isvoid;
 } xcb_protocol_request_t;
@@ -57,7 +56,7 @@ enum xcb_send_request_flags_t {
     XCB_REQUEST_DISCARD_REPLY = 1 << 2
 };
 
-unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request);
+unsigned int xcb_send_request(xcb_connection_t *c, int flags, struct iovec *vector, const xcb_protocol_request_t *request, xcb_extension_t *ext);
 
 
 /* xcb_in.c */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/xcb/attachments/20070511/22fe8812/attachment.pgp 


More information about the Xcb mailing list