memp.c
上传用户:yyhongfa
上传日期:2013-01-18
资源大小:267k
文件大小:7k
开发平台:

C/C++

  1. /*
  2.  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
  3.  * All rights reserved. 
  4.  * 
  5.  * Redistribution and use in source and binary forms, with or without modification, 
  6.  * are permitted provided that the following conditions are met:
  7.  *
  8.  * 1. Redistributions of source code must retain the above copyright notice,
  9.  *    this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright notice,
  11.  *    this list of conditions and the following disclaimer in the documentation
  12.  *    and/or other materials provided with the distribution.
  13.  * 3. The name of the author may not be used to endorse or promote products
  14.  *    derived from this software without specific prior written permission. 
  15.  *
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  17.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
  19.  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
  20.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
  21.  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
  22.  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
  23.  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
  24.  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
  25.  * OF SUCH DAMAGE.
  26.  *
  27.  * This file is part of the lwIP TCP/IP stack.
  28.  * 
  29.  * Author: Adam Dunkels <adam@sics.se>
  30.  *
  31.  */
  32. #include "lwip/opt.h"
  33. #include "lwip/memp.h"
  34. #include "lwip/pbuf.h"
  35. #include "lwip/udp.h"
  36. #include "lwip/raw.h"
  37. #include "lwip/tcp.h"
  38. #include "lwip/api.h"
  39. #include "lwip/api_msg.h"
  40. #include "lwip/tcpip.h"
  41. #include "lwip/sys.h"
  42. #include "lwip/stats.h"
  43. #include "uart.h"
  44. struct memp {
  45.   struct memp *next;
  46. };
  47. static struct memp *memp_tab[MEMP_MAX];
  48. static const u16_t memp_sizes[MEMP_MAX] = {
  49.   sizeof(struct pbuf),
  50.   sizeof(struct raw_pcb),
  51.   sizeof(struct udp_pcb),
  52.   sizeof(struct tcp_pcb),
  53.   sizeof(struct tcp_pcb_listen),
  54.   sizeof(struct tcp_seg),
  55.   sizeof(struct netbuf),
  56.   sizeof(struct netconn),
  57.   sizeof(struct api_msg),
  58.   sizeof(struct tcpip_msg),
  59.   //sizeof(struct sys_timeout)
  60. };
  61. static const u16_t memp_num[MEMP_MAX] = {
  62.   MEMP_NUM_PBUF,
  63.   MEMP_NUM_RAW_PCB,
  64.   MEMP_NUM_UDP_PCB,
  65.   MEMP_NUM_TCP_PCB,
  66.   MEMP_NUM_TCP_PCB_LISTEN,
  67.   MEMP_NUM_TCP_SEG,
  68.   MEMP_NUM_NETBUF,
  69.   MEMP_NUM_NETCONN,
  70.   MEMP_NUM_API_MSG,
  71.   MEMP_NUM_TCPIP_MSG,
  72.   //MEMP_NUM_SYS_TIMEOUT
  73. };
  74. static u8_t memp_memory[(MEMP_NUM_PBUF *
  75.        MEM_ALIGN_SIZE(sizeof(struct pbuf) +
  76.           sizeof(struct memp)) +
  77.       MEMP_NUM_RAW_PCB *
  78.        MEM_ALIGN_SIZE(sizeof(struct raw_pcb) +
  79.           sizeof(struct memp)) +
  80.       MEMP_NUM_UDP_PCB *
  81.        MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
  82.           sizeof(struct memp)) +
  83.       MEMP_NUM_TCP_PCB *
  84.        MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
  85.           sizeof(struct memp)) +
  86.       MEMP_NUM_TCP_PCB_LISTEN *
  87.        MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
  88.           sizeof(struct memp)) +
  89.       MEMP_NUM_TCP_SEG *
  90.        MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
  91.           sizeof(struct memp)) +
  92.       MEMP_NUM_NETBUF *
  93.        MEM_ALIGN_SIZE(sizeof(struct netbuf) +
  94.           sizeof(struct memp)) +
  95.       MEMP_NUM_NETCONN *
  96.        MEM_ALIGN_SIZE(sizeof(struct netconn) +
  97.           sizeof(struct memp)) +
  98.       MEMP_NUM_API_MSG *
  99.        MEM_ALIGN_SIZE(sizeof(struct api_msg) +
  100.           sizeof(struct memp)) +
  101.       MEMP_NUM_TCPIP_MSG *
  102.        MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
  103.           sizeof(struct memp)))];
  104. #if !SYS_LIGHTWEIGHT_PROT
  105. static sys_sem_t mutex;
  106. #endif
  107. #if MEMP_SANITY_CHECK
  108. static int
  109. memp_sanity(void)
  110. {
  111.   int i, c;
  112.   struct memp *m, *n;
  113.   for(i = 0; i < MEMP_MAX; i++) {
  114.     for(m = memp_tab[i]; m != NULL; m = m->next) {
  115.       c = 1;
  116.       for(n = memp_tab[i]; n != NULL; n = n->next) {
  117.          if (n == m) {
  118.           --c;
  119.         }
  120.         if (c < 0) return 0; /* LW was: abort(); */
  121.       }
  122.     }
  123.   }
  124.   return 1;
  125. }
  126. #endif /* MEMP_SANITY_CHECK*/
  127. void
  128. memp_init(void)
  129. {
  130.   struct memp *m, *memp;
  131.   u16_t i, j;
  132.   u16_t size;
  133.       
  134. #if MEMP_STATS
  135.   for(i = 0; i < MEMP_MAX; ++i) {
  136.     lwip_stats.memp[i].used = lwip_stats.memp[i].max =
  137.       lwip_stats.memp[i].err = 0;
  138.     lwip_stats.memp[i].avail = memp_num[i];
  139.   }
  140. #endif /* MEMP_STATS */
  141.   memp = (struct memp *)&memp_memory[0];
  142.   for(i = 0; i < MEMP_MAX; ++i) {
  143.     size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
  144.     if (memp_num[i] > 0) {
  145.       memp_tab[i] = memp;
  146.       m = memp;
  147.       
  148.       for(j = 0; j < memp_num[i]; ++j) {
  149.   m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
  150.   memp = m;
  151.   m = m->next;
  152.       }
  153.       memp->next = NULL;
  154.       memp = m;
  155.     } else {
  156.       memp_tab[i] = NULL;
  157.     }
  158.   }
  159. #if !SYS_LIGHTWEIGHT_PROT
  160.   mutex = sys_sem_new(1);
  161. #endif
  162.   
  163. }
  164. void *
  165. memp_malloc(memp_t type)
  166. {
  167.   struct memp *memp;
  168.   void *mem;
  169. #if SYS_LIGHTWEIGHT_PROT
  170.   SYS_ARCH_DECL_PROTECT(old_level);
  171. #endif
  172.  
  173.   LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
  174. #if SYS_LIGHTWEIGHT_PROT
  175.   SYS_ARCH_PROTECT(old_level);
  176. #else /* SYS_LIGHTWEIGHT_PROT */  
  177.   sys_sem_wait(mutex);
  178. #endif /* SYS_LIGHTWEIGHT_PROT */  
  179.   memp = memp_tab[type];
  180.   
  181.   if (memp != NULL) {    
  182.     memp_tab[type] = memp->next;    
  183.     memp->next = NULL;
  184. #if MEMP_STATS
  185.     ++lwip_stats.memp[type].used;
  186.     if (lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
  187.       lwip_stats.memp[type].max = lwip_stats.memp[type].used;
  188.     }
  189. #endif /* MEMP_STATS */
  190. #if SYS_LIGHTWEIGHT_PROT
  191.     SYS_ARCH_UNPROTECT(old_level);
  192. #else /* SYS_LIGHTWEIGHT_PROT */
  193.     sys_sem_signal(mutex);
  194. #endif /* SYS_LIGHTWEIGHT_PROT */  
  195.     LWIP_ASSERT("memp_malloc: memp properly aligned",
  196.      ((mem_ptr_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
  197.     mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
  198.     return mem;
  199.   } else {
  200.     LWIP_DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %dn", type));
  201. #if MEMP_STATS
  202.     ++lwip_stats.memp[type].err;
  203. #endif /* MEMP_STATS */
  204. #if SYS_LIGHTWEIGHT_PROT
  205.   SYS_ARCH_UNPROTECT(old_level);
  206. #else /* SYS_LIGHTWEIGHT_PROT */
  207.   sys_sem_signal(mutex);
  208. #endif /* SYS_LIGHTWEIGHT_PROT */  
  209.     return NULL;
  210.   }
  211. }
  212. void
  213. memp_free(memp_t type, void *mem)
  214. {
  215.   struct memp *memp;
  216. #if SYS_LIGHTWEIGHT_PROT
  217.   SYS_ARCH_DECL_PROTECT(old_level);
  218. #endif /* SYS_LIGHTWEIGHT_PROT */  
  219.  //DEBUG_FUNCTION("memp_free");
  220.   if (mem == NULL) {
  221.     return;
  222.   }
  223.   memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
  224. #if SYS_LIGHTWEIGHT_PROT
  225.     SYS_ARCH_PROTECT(old_level);
  226. #else /* SYS_LIGHTWEIGHT_PROT */  
  227.   sys_sem_wait(mutex);
  228. #endif /* SYS_LIGHTWEIGHT_PROT */  
  229. #if MEMP_STATS
  230.   lwip_stats.memp[type].used--; 
  231. #endif /* MEMP_STATS */
  232.   
  233.   memp->next = memp_tab[type]; 
  234.   memp_tab[type] = memp;
  235. #if MEMP_SANITY_CHECK
  236.   LWIP_ASSERT("memp sanity", memp_sanity());
  237. #endif  
  238. #if SYS_LIGHTWEIGHT_PROT
  239.   SYS_ARCH_UNPROTECT(old_level);
  240. #else /* SYS_LIGHTWEIGHT_PROT */
  241.   sys_sem_signal(mutex);
  242. #endif /* SYS_LIGHTWEIGHT_PROT */  
  243. }