lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] lwip does not use timeval structure and MEMP_MEM_MALLOC iss


From: Midnight Xiong
Subject: [lwip-devel] lwip does not use timeval structure and MEMP_MEM_MALLOC issue
Date: Thu, 20 May 2010 23:03:40 +0800

Hi,
(Please pardon me, I have no account in savannah)
#1 SO_RCVTIMEO issue in setsockopt() function.
In LwIP, it will support setsockopt() function for SO_RCVTIMEO. In BSD socket, it need a struct timeval *optval argurment. If the system has no struct timeval definition, this structure is provided in sockets.h file. However, in LwIP implementation, it's a msecond number.

#2, TCP pcb issue
In some small RAM system, lwip can use none-memory pool method and use MEMP_MEM_MALLOC macro to replace memp_malloc with mem_malloc. However, the state of TCP connection will change to TIME_WAIT when TCP connection is disconnected. If there are lots of TCP connection and then disconnect sometime, there are most TIME_WAIT TCP pcb in the system and exhaust all of system memory. To fix this issue, following is a patch:

static u16_t tcp_pcbs = 0;

void *
#if !MEMP_OVERFLOW_CHECK
memp_malloc(memp_t type)
#else
memp_malloc_fn(memp_t type, const char* file, const int line)
#endif
{
#if !MEMP_MEM_MALLOC
  struct memp *memp;
  SYS_ARCH_DECL_PROTECT(old_level);
 
  LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;);

  SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK >= 2
  memp_overflow_check_all();
#endif /* MEMP_OVERFLOW_CHECK >= 2 */

  memp = memp_tab[type];
 
  if (memp != NULL) {
    memp_tab[type] = memp->next;
#if MEMP_OVERFLOW_CHECK
    memp->next = NULL;
    memp->file = file;
    memp->line = line;
#endif /* MEMP_OVERFLOW_CHECK */
    MEMP_STATS_INC_USED(used, type);
    LWIP_ASSERT("memp_malloc: memp properly aligned",
                ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0);
    memp = (struct memp*)((u8_t*)memp + MEMP_SIZE);
  } else {
    LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", memp_desc[type]));
    MEMP_STATS_INC(err, type);
  }
  SYS_ARCH_UNPROTECT(old_level);

  return memp;
#else
  void* ptr;
  u32_t size;
  SYS_ARCH_DECL_PROTECT(old_level);

  size = memp_sizes[type];
  LWIP_DEBUGF(MEMP_DEBUG, ("memp malloc %s, size %d, ", memp_desc[type], memp_sizes[type]));

  SYS_ARCH_PROTECT(old_level);
  if (type == MEMP_TCP_PCB)
  {
    if (tcp_pcbs >= MEMP_NUM_TCP_PCB)
    {
      SYS_ARCH_UNPROTECT(old_level);
      return NULL;
    }
    else
    {
      /* increased tcp pcb allocated number */
      tcp_pcbs ++;
    }
  }
  SYS_ARCH_UNPROTECT(old_level);

  ptr = mem_malloc(size);
  LWIP_DEBUGF(MEMP_DEBUG, ("mem 0x%x\n", ptr));

  return ptr;
#endif /* MEMP_MEM_MALLOC */
}

void
memp_free(memp_t type, void *mem)
{
#if !MEMP_MEM_MALLOC
  struct memp *memp;
  SYS_ARCH_DECL_PROTECT(old_level);

  if (mem == NULL) {
    return;
  }
  LWIP_ASSERT("memp_free: mem properly aligned",
                ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0);

  memp = (struct memp *)((u8_t*)mem - MEMP_SIZE);

  SYS_ARCH_PROTECT(old_level);
#if MEMP_OVERFLOW_CHECK
#if MEMP_OVERFLOW_CHECK >= 2
  memp_overflow_check_all();
#else
  memp_overflow_check_element(memp, memp_sizes[type]);
#endif /* MEMP_OVERFLOW_CHECK >= 2 */
#endif /* MEMP_OVERFLOW_CHECK */

  MEMP_STATS_DEC(used, type);
 
  memp->next = memp_tab[type];
  memp_tab[type] = memp;

#if MEMP_SANITY_CHECK
  LWIP_ASSERT("memp sanity", memp_sanity());
#endif /* MEMP_SANITY_CHECK */

  SYS_ARCH_UNPROTECT(old_level);
#else
  SYS_ARCH_DECL_PROTECT(old_level);

  SYS_ARCH_PROTECT(old_level);
  if (type == MEMP_TCP_PCB && mem)
  {
    tcp_pcbs --;
  }
  SYS_ARCH_UNPROTECT(old_level);

  LWIP_DEBUGF(MEMP_DEBUG, ("memp free %s, mem 0x%x\n", memp_desc[type], mem));
  /* release this memory */
  mem_free(mem);
#endif /* MEMP_MEM_MALLOC */
}

In this patch, a static variable tcp_pcbs is introduced to record the maximum allocated TCP pcb. If the allocated TCP pcb number is great than the system setting, NULL will be returned. According to lwip implementaion, if the return of memp_malloc for TCP pcb allocation is NULL, it will use some one in TIME_WAIT TCP pcb.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]