[Xcb] [PATCH] XCB-XML: Proposal for alignment padding

Evgeny M. Zubok evgeny.zubok at tochka.ru
Tue Nov 9 08:10:01 PST 2010


Julien Cristau <jcristau at debian.org>
writes:

> Don't you need to know the size of the request anyway?  Also I'd rather
> have that work done in the code generator than in the xml description,
> to keep that as readable as possible (and incidentally, avoid
> introducing new bugs there).  Maybe that's just me though.

If you decide that idea of expression is redundant I will not be against
that. I try to clarify my solution once again by example from the code
generator's point of view.

1. <pad align="integer"> is required bacause there are sequences of
not-aligned lists without intermediate padding (in xkb, for
example). The <pad> tag is intended to distinguish the cases when the
list requires padding and when it doesn't. Now we are able to get rid
from unnecessary padding code after the lists where this code is not
required (one minor optimization).

2. About the expression inside pad. It is up to code generator to take
into account the expression. Even if the expression is present, the code
generator is free to ignore it and generate code using only the align
attribute.

An hypotetical example:

1    CARD8		string_len (s)
1    CARD8		bytes_len (b)
1    CARD8   		uints_len (u)
21 	     		unused
2u   LISTofCARD32	uints list
4    CARD32    		dummy
2s   LISTofCARD8   	string
p            		unused, p=pad(2s)
2b   LISTofCARD8	bytes
q			unused, q=pad(2b)


Scenario A (pad without expression or expression is ignored)
------------------------------------------------------------

Then the <pad align="integer" /> should have the meaning "pad total
length of structure at this place to be multiple of 'align'". XML
descripion is:

<pad bytes="1">
<field type="CARD8" name="string_len" />
<field type="CARD8" name="bytes_len" />
<field type="CARD8" name="uints_len" />
<pad bytes="1" />
<list type="CARD32" name="uints">
  <fieldref>uints_len</fieldref>
</list>
<field type="CARD32" name="dummy" />
<list type="char" name="string">
  <fieldref>string_len</fieldref>
</list>
<pad align="4" /> <!-- pad1 -->
<list type="CARD8" name="bytes">
  <fieldref>bytes_len</fieldref>
</list>
<pad align="4" /> <!-- pad 2 -->


Code generator should collect a total size of structure. In the common
case we shouldn't calculate the alignment only from the size of the
previous entity without explicit information. Also we can reset total to
0 after each alignment. Pseudocode:


/* total = 0 */
8 bytes (opcode, length, sequence, data) 
insert_field string_len
insert_field bytes_len
insert_field uints_len
insert_pad 1           /* total is 12, padding -> reset total to 0 */
insert_list uints_len
insert_field dummy
insert_list string
insert_pad pad1(uints_len * sizeof(uint32_t)
                + sizeof(uint32_t)
                + string_len * sizeof(char)) /* reset total to 0 */
insert_list bytes
insert_pad pad2(bytes_len * sizeof(uint8_t)) /* reset total to 0 */

We could eliminate uints_len from pad1 as like as sizeof(uint32_t). But
in order to do that we must provide a size analysis in the code
generator to ensure that the size of list 'uints' is always multiple of
4. The LISTofCARD32 is a simple case. Some types like XID, DRAWABLE,
LISTofCOLORs, LISTofSCREENS, LISTofCARD8 with the length as an
expression are more complex for the size analysis.


Scenario B (with expressions)
-----------------------------

<pad bytes="1">
<field type="CARD8" name="string_len" />
<field type="CARD8" name="bytes_len" />
<field type="CARD8" name="uints_len" />
<pad bytes="21" />
<list type="CARD32" name="uints">
  <fieldref>uints_len</fieldref>
</list>
<field type="CARD32" name="dummy" />
<list type="char" name="string">
  <fieldref>string_len</fieldref>
</list>
<pad align="4"><sizeof>string</sizeof></pad> <!-- pad1 -->
<list type="CARD8" name="bytes">
  <fieldref>bytes_len</fieldref>
</list>
<pad align="4"><sizeof>bytes</sizeof></pad>  <!-- pad 2 -->

When code generator collects entities it remembers their length
expressions and inserts them when they are referenced by <sizeof> tag.

Pseudocode:

8 bytes (opcode, length, sequence, data)
insert_field string_len
insert_field bytes_len
insert_field uints_len
insert_list uints_len
insert_field dummy
insert_list string
insert_pad pad1(string_len * sizeof(char))
insert_list bytes
insert_pad pad2(bytes_len * sizeof(uint8_t))

(yet another minor optimization)



More information about the Xcb mailing list