Стек Saving путем прямого вписывания в отправить буфер ниже

Обработка изображений наличия стопки протоколов и некоторого кода c/cpp, который аккуратно касается отправки на каждом слое. Каждый отправляет, функция использует слой ниже для добавления другого заголовка, пока целое сообщение в конечном счете не помещается в непрерывный глобальный буфер на уровне 0:

void SendLayer2(void * payload, unsigned int payload_length)
{
  Layer2Header header;   /* eat some stack */
  const int msg_length = sizeof(header) + payload_length;

  char msg[msg_length];  /* and have some more */
  memset(msg, 0, sizeof(msg));

  header.whatever = 42;
  memcpy(&buffer[sizeof(header)], payload, payload_length);

  SendLayer1(buffer, msg_length);
}

void SendLayer1(void * payload, unsigned int payload_length)
{
  Layer1Header header;   /* eat some stack */
  const int msg_length = sizeof(header) + payload_length;

  char msg[msg_length];  /* and have some more */
  memset(msg, 0, sizeof(msg));

  header.whatever = 42;
  memcpy(&buffer[sizeof(header)], payload, payload_length);

  SendLayer0(buffer, msg_length);
}

Теперь данные перемещены в некоторую глобальную переменную и на самом деле переданы:

char globalSendBuffer[MAX_MSG_SIZE];
void SendLayer0(void * payload, unsigned int payload_length)
{
  // Some clever locking for the global buffer goes here

  memcpy(globalSendBuffer, payload, payload_length);
  SendDataViaCopper(globalSendBuffer, payload_length);
}

Я хотел бы уменьшить и использование стека и количество memcpy () s в этом коде, таким образом, я воображаю что-то как:

void SendLayer2(void * payload, unsigned int payload_length)
{            
  Layer2Header * header = GetHeader2Pointer();
  header->whatever = 42;

  void * buffer = GetPayload2Pointer();
  memcpy(buffer, payload, payload_length);

  ...
}

Моя идея состояла бы в том, чтобы иметь что-то внизу, которое вычислит надлежащие смещения для каждого заголовка слоев и смещение для фактической полезной нагрузки путем непрерывного вычитания из MAX_MSG_SIZE, и разрешение верхнему уровню кодировать затем заполняет глобальный буфер непосредственно от конца / правая сторона.

Это звучит разумным? Существует ли альтернатива, возможно, более изящные подходы?

1
задан dantje 21 July 2010 в 19:38
поделиться

2 ответа

Возможно, вас заинтересует эта статья: «Сетевые буферы и управление памятью» Алана Кокса. По сути, у вас есть буфер и несколько указателей на разные интересные части этого буфера: заголовки протокола, данные, ... Первоначально вы резервируете некоторое пространство для заголовков, устанавливая указатель данных на (buffer_start + max_headers_size), и каждый уровень получает указатель ближе к началу буфера.

Я уверен, что где-то должно быть подобное описание для mbufs BSD.

РЕДАКТИРОВАТЬ:

Дэвид Миллер (специалист по поддержке сетей Linux) написал статью «Как работают SKB»

2
ответ дан 2 September 2019 в 22:51
поделиться

Это звучит как «Нулевое копирование». Я не эксперт, поэтому ищите этот термин, и вы найдете всевозможные ссылки.

0
ответ дан 2 September 2019 в 22:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: