Как выполнить выравнивание структуры данных с помощью kmalloc? - PullRequest
0 голосов
/ 15 марта 2011

Я читал выравнивание структуры данных статей, но ничего не получилось. Возможно, все слишком сложно для меня, чтобы понять. Я также наткнулся на заполнение структуры данных , которое также необходимо для выравнивания данных. Как добавить заполнение структуры данных в структуру usb_ep? Также, как мне убедиться, что всякий раз, когда я выполняю kmalloc, данные для чтения должны иметь смещение памяти, кратное 4?

Ответы [ 2 ]

3 голосов
/ 15 марта 2011

Что касается выравнивания, kmalloc правильно выровняет структуры.Если у вас есть 4-байтовая переменная, она будет выровнена на 4 байта, если у вас есть 8-байтовая переменная, выровнена на 8 байт.Понимание выравнивания - причина, по которой необходимо заполнение.

То, что вы не хотите получать, это заполнение Гарбаде между переменными в вашей структуре.Вы можете сделать это с помощью директивы pragma pack (возможно, самой простой) или добавив заполнение вручную.

Пример

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

Размер всех элементов составляет 8 байтов, но из-за требований выравнивания размер будет 12 байтов.Схема памяти будет выглядеть следующим образом:

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

Чтобы не допустить заполнения или увеличения размера структуры, вы можете переставить элементы, чтобы удовлетворить требования выравнивания.

Это имеет структуру:

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

Будет иметь размер 8 байт и не требует добавления отступов.

1 голос
/ 15 марта 2011

Это происходит от 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.

Лучший способ дополнить поля в структуре - объявить переменные по убыванию. Итак, сначала самые большие, потом самые маленькие.

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

Это не всегда приводит к логически связанным элементам в структуре, но обычно дает наиболее компактное и легкодоступное использование памяти.

Вы можете использовать байты заполнения в своих объявлениях структуры, но они загромождают код и не гарантируют компактные структуры. Компилятор может выровнять каждый байт на 4-байтовой границе, так что вы можете получить

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

принимает 4 байта для a, 4 байта для заполнения1, 4 байта для b и 4 байта для заполнения2. Некоторые компиляторы позволяют вам указывать упакованные структуры, которые в этом случае будут давать правильный результат. Обычно я просто объявляю поля от самых больших до самых маленьких типов и оставляю это на этом. Если вам нужно разделить память между двумя языками / компиляторами, то вам нужно убедиться, что структуры одинаково выравниваются в памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...