LoginSignup
1
1

More than 5 years have passed since last update.

uIPの実装 メモリ管理を読む

Posted at

uIPの実装 メモリ管理を読む

uIPはlwIPの作者 Adam Dunkels が開発したTCP/IPプロトコルスタックです。lwUPよりも小さい環境で動作します。

ソース

uIPのメモリ管理

  • アプリ側で管理するメモリはメモリプールで管理。
  • 受信パケットは1個のバッファを使いまわす。

メモリプール

メモリプールの宣言

  • MEMBマクロで宣言する
  • linemem はメモリプール制御用の構造体
  • struct telnetd_line はメモリプールのブロックサイズ
  • TELNETD_CONF_NUMLINESはメモリブロックの個数
MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);

メモリプールの初期化

  • m->count は各メモリブロックのリファレンスカウント 0なら未使用 1なら仕様中う
  • m->memはメモリプールのポインタ c:memb.c void memb_init(struct memb_blocks *m) { memset(m->count, 0, m->num); memset(m->mem, 0, m->size * m->num); }

メモリプールからブロックの取得

memb.c
memb_alloc(struct memb_blocks *m)
{
  int i;

  for(i = 0; i < m->num; ++i) {
    if(m->count[i] == 0) {
      /* If this block was unused, we increase the reference count to
     indicate that it now is used and return a pointer to the
     memory block. */
      ++(m->count[i]);
      return (void *)((char *)m->mem + (i * m->size));
    }
  }

  /* No free block was found, so we return NULL to indicate failure to
     allocate block. */
  return NULL;
}

メモリブロックの解放

memb.c
char
memb_free(struct memb_blocks *m, void *ptr)
{
  int i;
  char *ptr2;

  /* Walk through the list of blocks and try to find the block to
     which the pointer "ptr" points to. */
  ptr2 = (char *)m->mem;
  for(i = 0; i < m->num; ++i) {

    if(ptr2 == (char *)ptr) {
      /* We've found to block to which "ptr" points so we decrease the
     reference count and return the new value of it. */
      if(m->count[i] > 0) {
    /* Make sure that we don't deallocate free memory. */
    --(m->count[i]);
      }
      return m->count[i];
    }
    ptr2 += m->size;
  }
  return -1;
}

受信パケットバッファ

  • 1個分の静的なパケットバッファを使いまわす。 デフォルトのサイズは400+2バイト
uipopt.h
/**
 * The size of the uIP packet buffer.
 *
 * The uIP packet buffer should not be smaller than 60 bytes, and does
 * not need to be larger than 1500 bytes. Lower size results in lower
 * TCP throughput, larger size results in higher TCP throughput.
 *
 * \hideinitializer
 */
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE     400
#else /* UIP_CONF_BUFFER_SIZE */
#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
#endif /* UIP_CONF_BUFFER_SIZE */
uip.c
u8_t uip_buf[UIP_BUFSIZE + 2];   /* The packet buffer that contains
                    incoming packets. */
  • uip.c でのパケットバッファアクセス用のマクロ
uip.c
/* Macros. */
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1