/*
 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
 * All rights reserved. 
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
 * OF SUCH DAMAGE.
 *
 * This file is part of the lwIP TCP/IP stack.
 * 
 * Author: Adam Dunkels <adam@sics.se>
 *
 */

#include "lwip/opt.h"

#include "lwip/memp.h"

#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/raw.h"
#include "lwip/tcp.h"
#include "lwip/api.h"
#include "lwip/api_msg.h"
#include "lwip/tcpip.h"

#include "lwip/sys.h"
#include "lwip/stats.h"

struct memp {
  struct memp *next;
};



static struct memp *memp_tab[MEMP_MAX];

static const u16_t memp_sizes[MEMP_MAX] = {
  sizeof(struct pbuf),
  sizeof(struct raw_pcb),
  sizeof(struct udp_pcb),
  sizeof(struct tcp_pcb),
  sizeof(struct tcp_pcb_listen),
  sizeof(struct tcp_seg),
  sizeof(struct netbuf),
  sizeof(struct netconn),
  sizeof(struct api_msg),
  sizeof(struct tcpip_msg),
  sizeof(struct sys_timeout)
};

static const u16_t memp_num[MEMP_MAX] = {
  MEMP_NUM_PBUF,
  MEMP_NUM_RAW_PCB,
  MEMP_NUM_UDP_PCB,
  MEMP_NUM_TCP_PCB,
  MEMP_NUM_TCP_PCB_LISTEN,
  MEMP_NUM_TCP_SEG,
  MEMP_NUM_NETBUF,
  MEMP_NUM_NETCONN,
  MEMP_NUM_API_MSG,
  MEMP_NUM_TCPIP_MSG,
  MEMP_NUM_SYS_TIMEOUT
};

static u8_t memp_memory[(MEMP_NUM_PBUF *
       MEM_ALIGN_SIZE(sizeof(struct pbuf) +
          sizeof(struct memp)) +
      MEMP_NUM_RAW_PCB *
       MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +
          sizeof(struct memp)) +
      MEMP_NUM_UDP_PCB *
       MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
          sizeof(struct memp)) +
      MEMP_NUM_TCP_PCB *
       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
          sizeof(struct memp)) +
      MEMP_NUM_TCP_PCB_LISTEN *
       MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
          sizeof(struct memp)) +
      MEMP_NUM_TCP_SEG *
       MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
          sizeof(struct memp)) +
      MEMP_NUM_NETBUF *
       MEM_ALIGN_SIZE(sizeof(struct netbuf) +
          sizeof(struct memp)) +
      MEMP_NUM_NETCONN *
       MEM_ALIGN_SIZE(sizeof(struct netconn) +
          sizeof(struct memp)) +
      MEMP_NUM_API_MSG *
       MEM_ALIGN_SIZE(sizeof(struct api_msg) +
          sizeof(struct memp)) +
      MEMP_NUM_TCPIP_MSG *
       MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
          sizeof(struct memp)) +
      MEMP_NUM_SYS_TIMEOUT *
       MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
          sizeof(struct memp)))];


#if !SYS_LIGHTWEIGHT_PROT
static sys_sem_t mutex;
#endif

#ifndef LWIP_NOASSERT
static int
memp_sanity(void)
{
  int i, c;
  struct memp *m, *n;

  for(i = 0; i < MEMP_MAX; i++) {
    for(m = memp_tab[i]; m != NULL; m = m->next) {
      c = 1;
      for(n = memp_tab[i]; n != NULL; n = n->next) {
         if (n == m) {
          --c;
        }
        if (c < 0) return 0; /* LW was: abort(); */
      }
    }
  }
  return 1;
}
#endif /* LWIP_DEBUG */

void
memp_init(void)
{
  struct memp *m, *memp;
  u16_t i, j;
  u16_t size;
      
#if MEMP_STATS
  for(i = 0; i < MEMP_MAX; ++i) {
    lwip_stats.memp[i].used = lwip_stats.memp[i].max =
      lwip_stats.memp[i].err = 0;
    lwip_stats.memp[i].avail = memp_num[i];
  }
#endif /* MEMP_STATS */

  memp = (struct memp *)&memp_memory[0];
  for(i = 0; i < MEMP_MAX; ++i) {
    size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
    if (memp_num[i] > 0) {
      memp_tab[i] = memp;
      m = memp;
      
      for(j = 0; j < memp_num[i]; ++j) {
  m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
  memp = m;
  m = m->next;
      }
      memp->next = NULL;
      memp = m;
    } else {
      memp_tab[i] = NULL;
    }
  }

#if !SYS_LIGHTWEIGHT_PROT
  mutex = sys_sem_new(1);
#endif

  
}

void *
memp_malloc(memp_t type)
{
  struct memp *memp;
  void *mem;
#if SYS_LIGHTWEIGHT_PROT
  SYS_ARCH_DECL_PROTECT(old_level);
#endif
 
  LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);

#if SYS_LIGHTWEIGHT_PROT
  SYS_ARCH_PROTECT(old_level);
#else /* SYS_LIGHTWEIGHT_PROT */  
  sys_sem_wait(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */  

  memp = memp_tab[type];
  
  if (memp != NULL) {    
    memp_tab[type] = memp->next;    
    memp->next = NULL;
#if MEMP_STATS
    ++lwip_stats.memp[type].used;
    if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
      lwip_stats.memp[type].max = lwip_stats.memp[type].used;
    }
#endif /* MEMP_STATS */
#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_UNPROTECT(old_level);
#else /* SYS_LIGHTWEIGHT_PROT */
    sys_sem_signal(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */  
    LWIP_ASSERT("memp_malloc: memp properly aligned",
     ((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);

    mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
    return mem;
  } else {
    LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
#if MEMP_STATS
    ++lwip_stats.memp[type].err;
#endif /* MEMP_STATS */
#if SYS_LIGHTWEIGHT_PROT
  SYS_ARCH_UNPROTECT(old_level);
#else /* SYS_LIGHTWEIGHT_PROT */
  sys_sem_signal(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */  
    return NULL;
  }
}

void
memp_free(memp_t type, void *mem)
{
  struct memp *memp;
#if SYS_LIGHTWEIGHT_PROT
  SYS_ARCH_DECL_PROTECT(old_level);
#endif /* SYS_LIGHTWEIGHT_PROT */  

  if (mem == NULL) {
    return;
  }
  memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));

#if SYS_LIGHTWEIGHT_PROT
    SYS_ARCH_PROTECT(old_level);
#else /* SYS_LIGHTWEIGHT_PROT */  
  sys_sem_wait(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */  

#if MEMP_STATS
  lwip_stats.memp[type].used--; 
#endif /* MEMP_STATS */
  
  memp->next = memp_tab[type]; 
  memp_tab[type] = memp;

  LWIP_ASSERT("memp sanity", memp_sanity());

#if SYS_LIGHTWEIGHT_PROT
  SYS_ARCH_UNPROTECT(old_level);
#else /* SYS_LIGHTWEIGHT_PROT */
  sys_sem_signal(mutex);
#endif /* SYS_LIGHTWEIGHT_PROT */  
}

