开发者

how to perform data structure alignment with kmalloc?

I have been reading data structure alignment articles but I'm getting nowhere. Perhaps things are just too complicated for me to understand. I also came across data structure padding which is also necessary to align data. How do I add a data structure padding to struct usb_ep? Also how do I m开发者_StackOverflow社区ake sure that whenever I perform kmalloc the data to be read should be at a memory offset which is some multiple of 4?


Regarding alignment, kmalloc will align the structures properly. If you have an 4byte variable, it will be 4bytes aligned, if you have an 8byte vaiable, it will be 8bytes aligned. Understanding alignment is the reason why padding is needed.

What you dont want to get is garbade padding between the variables in your struct. You can do that with the pragma pack directive (probably easiest) or by adding the padding manually.

Example

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

The size of all the elements is 8bytes, but due to alignment requirements, the size will be 12bytes. Memory layout would be like this:

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

In order to not get any padding, or increasing the size of the struct, you can rearrange elements in order to satisfy the alignment requirements.

That is having a struct:

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

Will have the size of 8bytes, and no requirement for adding padding.


This comes from 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.

The best way to pad fields in a structure is to declare your variables in descending size. So your largest ones first, then down to the smallest.

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

This doesn't always end up with logically connected items in the structure, but will typically give the most compact and easily accessible memory usage.

You can use use padding bytes in your struct declarations, but they clutter up the code, and do not guarantee compact structures. A compiler may align every byte on a 4 byte boundary, so you might end up with

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

taking 4 bytes for a, 4 bytes for padding1, 4 bytes for b, and 4 bytes for padding2. Some compilers allow you to specify packed structures which would yield the correct result in this case. Usually I just declare the fields from largest to smallest types and leave it at that. If you need to share memory between two langages/compilers, then you need to make sure the structs align identically in memory.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜