4.1.2 Creating foreign structure types

4.1.2.3 Alignment requirements

Often computer hardware or software places certain restrictions on operations that read from or write to memory, especially those that affect more than 1 byte of memory. Examples of such operations are those involving double floating-point numbers and 32-bit integers. In particular, for some machines that use 8-bit byte addressing and that have special floating-point hardware, an error occurs when you try to access a single-precision floating-point number from an address not divisible by 4. On some machines, access instructions for double-precision floating-point numbers can be executed only on addresses that are divisible by 8.

To model these sorts of restrictions for data alignment, predefined and user-defined foreign types have alignment requirements. These alignment requirements determine the starting address of a foreign type as follows:

Two integer valuesR andM are associated with any foreign type; these values are called the remainder and modulus respectively, and they must be in the range 0R <M 4095. When you use the functionmake-foreign-pointer or the constructor function associated withdef-foreign-struct to define a foreign type, any foreign storage of that type is constructed to start at a machine address that is congruent toR moduloM.

If the first element in a packed array of elements of a fixed-sized type is aligned, the rest of the elements are also aligned. Thus, the size of any foreign storage of typenewtype with modulusM must be a multiple ofM. If a foreign structure typestruct-type has a component typecomp-type, the modulus ofcomp-type must divide the modulus ofstruct-type.

For example, assume that the foreign type:unsigned-32bit has alignment modulus 1 and remainder 0. The foreign typecomp-type is of size 8 bytes and has modulus 8 and remainder 3. The foreign typestruct-type, which contains these components, is defined by the following expression:

(def-foreign-struct (struct-type
                      (:alignment (:modulus 16 :remainder 4)))
  (slot-1 :type :unsigned-32bit)
  (slot-2 :type comp-type))

Thus, the foreign storage typestruct-type has two components and two instances of alignment padding, as shown in Table 4.1.

Alignment of a foreign storage type
OffsetSlot Name Slot Size
0slot-14 bytes
4padding 3 bytes
7slot-28 bytes
15padding 1 byte

There are no alignment requirements for the foreign typeslot-1--it can fit anywhere in the structure; thus, it starts at offset 0 and occupies 4 bytes. The alignment for the foreign typeslot-2 requires that it start at the offset 7 with respect to the foreign type struct-type; that is, the alignment of the foreign typeslot-2 is (7 + 4) = 11, which is congruent to 3 modulo 8. Thus, 3 bytes of padding are inserted between the two slots. The final padding fills out the structure to 16 bytes.

If the starting address ofstruct-type were changed by adding or subtracting any multiple of 16, the internal layout of the foreign storage would not be affected. If the alignment requirements forcomp-type were modulus 32 and remainder 11, it would not be possible to specify the internal layout of thestruct-type foreign storage.

It is illegal for a slot type to have a modulus that does not divide the modulus of its parent structure type. The functionsforeign-type-modulus andforeign-type-remainder return the modulus and alignment values for foreign types respectively.


The Advanced User's Guide - 9 SEP 1996

Generated with Harlequin WebMaker