comment effectuer l’alignement de la structure de données avec kmalloc?

Je lisais des articles sur l’ alignement des structures de données, mais je n’arrivais à rien. Peut-être que les choses sont trop compliquées pour que je puisse comprendre. Je suis également tombé sur le remplissage de la structure de données, qui est également nécessaire pour aligner les données. Comment append un remplissage de structure de données à struct usb_ep? Aussi, comment puis-je m’assurer que chaque fois que j’effectue kmalloc, les données à lire doivent se trouver à un décalage de mémoire qui est un multiple de 4?

En ce qui concerne l’alignement, kmalloc alignera correctement les structures. Si vous avez une variable de 4 octets, elle sera alignée sur 4 octets; si vous avez un fichier 8 octets disponible, elle sera alignée sur 8 octets. Comprendre l’alignement est la raison pour laquelle le remplissage est nécessaire.

Ce que vous ne voulez pas obtenir, c’est un bourrage entre les variables de votre structure. Vous pouvez le faire avec la directive pragma pack (probablement la plus simple) ou en ajoutant le remplissage manuellement.

Exemple

struct usb_ep { short a; /* 2 bytes*/ int b; /* 4 bytes*/ short c; /* 2 bytes*/ }; 

La taille de tous les éléments est de 8 octets, mais en raison des exigences d’alignement, elle sera de 12 octets. La disposition de la mémoire ressemblerait à ceci:

 short a - 2 bytes char pad[2] - 2 bytes of padding int b - 4 bytes short c - 2 bytes char pad[2] - 2 bytes of padding 

Afin de ne pas obtenir de remplissage ou d’augmenter la taille de la structure, vous pouvez réorganiser les éléments afin de satisfaire les exigences d’alignement.

C’est avoir une structure:

 struct usb_ep { short a; /* 2 bytes*/ short c; /* 2 bytes*/ int b; /* 4 bytes*/ }; 

Aura la taille de 8 octets et ne nécessitera pas l’ajout de rembourrage.

Cela vient de http://minirighi.sourceforge.net/html/kmalloc_8c.html

 void * kmemalign (size_t alignment, size_t size) Allocate some memory aligned to a boundary. Parameters: alignment The boundary. size The size you want to allocate. Exceptions: NULL Out-of-memory. Returns: A pointer to a memory area aligned to the boundary. The pointer is a aligned_mem_block_t pointer, so if you want to access to the data area of this pointer you must specify the p->start filed. Note: Use kfree(void *ptr) to free the allocated block. 

La meilleure façon de remplir les champs d’une structure est de déclarer vos variables avec une taille décroissante. Donc, les plus gros d’abord, puis les plus petits.

 struct example { double amount; char *name; int cnt; char is_valid; }; 

Cela ne se termine pas toujours avec des éléments logiquement connectés dans la structure, mais donnera généralement l’utilisation de la mémoire la plus compacte et facilement accessible.

Vous pouvez utiliser des octets de remplissage dans vos déclarations de structure, mais ils encombrent le code et ne garantissent pas des structures compactes. Un compilateur peut aligner chaque octet sur une limite de 4 octets, de sorte que vous pourriez vous retrouver avec

 struct example2 { char a; char padding1[3]; char b; char padding2[3]; }; 

prendre 4 octets pour a, 4 octets pour padding1, 4 octets pour b et 4 octets pour padding2. Certains compilateurs vous permettent de spécifier des structures compactes qui donneraient le résultat correct dans ce cas. Habituellement, je déclare simplement les champs du plus grand au plus petit et le rest. Si vous avez besoin de partager de la mémoire entre deux langages / compilateurs, vous devez vous assurer que les structures s’alignent de manière identique dans la mémoire.