]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/blob - src/core/memp.c
Allow minimal unix target to build in cygwin (but not necessarily run).
[pes-rpp/rpp-lwip.git] / src / core / memp.c
1 /*
2  * Copyright (c) 2001-2003 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
33 #include "lwipopts.h"
34
35 #include "lwip/memp.h"
36
37 #include "lwip/pbuf.h"
38 #include "lwip/udp.h"
39 #include "lwip/tcp.h"
40 #include "lwip/api.h"
41 #include "lwip/api_msg.h"
42 #include "lwip/tcpip.h"
43
44 #include "lwip/sys.h"
45 #include "lwip/stats.h"
46
47 struct memp {
48   struct memp *next;
49 };
50
51
52
53 static struct memp *memp_tab[MEMP_MAX];
54
55 static const u16_t memp_sizes[MEMP_MAX] = {
56   sizeof(struct pbuf),
57   sizeof(struct udp_pcb),
58   sizeof(struct tcp_pcb),
59   sizeof(struct tcp_pcb_listen),
60   sizeof(struct tcp_seg),
61   sizeof(struct netbuf),
62   sizeof(struct netconn),
63   sizeof(struct api_msg),
64   sizeof(struct tcpip_msg),
65   sizeof(struct sys_timeout)
66 };
67
68 static const u16_t memp_num[MEMP_MAX] = {
69   MEMP_NUM_PBUF,
70   MEMP_NUM_UDP_PCB,
71   MEMP_NUM_TCP_PCB,
72   MEMP_NUM_TCP_PCB_LISTEN,
73   MEMP_NUM_TCP_SEG,
74   MEMP_NUM_NETBUF,
75   MEMP_NUM_NETCONN,
76   MEMP_NUM_API_MSG,
77   MEMP_NUM_TCPIP_MSG,
78   MEMP_NUM_SYS_TIMEOUT
79 };
80
81 static u8_t memp_memory[(MEMP_NUM_PBUF *
82                          MEM_ALIGN_SIZE(sizeof(struct pbuf) +
83                                         sizeof(struct memp)) +
84                         MEMP_NUM_UDP_PCB *
85                          MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
86                                         sizeof(struct memp)) +
87                         MEMP_NUM_TCP_PCB *
88                          MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
89                                         sizeof(struct memp)) +
90                         MEMP_NUM_TCP_PCB_LISTEN *
91                          MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
92                                         sizeof(struct memp)) +
93                         MEMP_NUM_TCP_SEG *
94                          MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
95                                         sizeof(struct memp)) +
96                         MEMP_NUM_NETBUF *
97                          MEM_ALIGN_SIZE(sizeof(struct netbuf) +
98                                         sizeof(struct memp)) +
99                         MEMP_NUM_NETCONN *
100                          MEM_ALIGN_SIZE(sizeof(struct netconn) +
101                                         sizeof(struct memp)) +
102                         MEMP_NUM_API_MSG *
103                          MEM_ALIGN_SIZE(sizeof(struct api_msg) +
104                                         sizeof(struct memp)) +
105                         MEMP_NUM_TCPIP_MSG *
106                          MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
107                                         sizeof(struct memp)) +
108                         MEMP_NUM_SYS_TIMEOUT *
109                          MEM_ALIGN_SIZE(sizeof(struct sys_timeout) +
110                                         sizeof(struct memp)))];
111
112 /*-----------------------------------------------------------------------------------*/
113 #ifndef SYS_LIGHTWEIGHT_PROT
114 static sys_sem_t mutex;
115 #endif
116 /*-----------------------------------------------------------------------------------*/
117 #ifdef LWIP_DEBUG
118 static int
119 memp_sanity(void)
120 {
121   int i, c;
122   struct memp *m, *n;
123
124   for(i = 0; i < MEMP_MAX; i++) {
125     for(m = memp_tab[i]; m != NULL; m = m->next) {
126       c = 1;
127       for(n = memp_tab[i]; n != NULL; n = n->next) {
128         if(n == m) {
129                 --c;
130         }
131               if(c < 0) return 0; /* LW was: abort(); */
132       }
133     }
134   }
135   return 1;
136 }
137 #endif /* LWIP_DEBUG */
138 /*-----------------------------------------------------------------------------------*/
139 void
140 memp_init(void)
141 {
142   struct memp *m, *memp;
143   u16_t i, j;
144   u16_t size;
145       
146 #ifdef MEMP_STATS
147   for(i = 0; i < MEMP_MAX; ++i) {
148     lwip_stats.memp[i].used = lwip_stats.memp[i].max =
149       lwip_stats.memp[i].err = 0;
150     lwip_stats.memp[i].avail = memp_num[i];
151   }
152 #endif /* MEMP_STATS */
153
154   memp = (struct memp *)&memp_memory[0];
155   for(i = 0; i < MEMP_MAX; ++i) {
156     size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
157     if(memp_num[i] > 0) {
158       memp_tab[i] = memp;
159       m = memp;
160       
161       for(j = 0; j < memp_num[i]; ++j) {
162         m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
163         memp = m;
164         m = m->next;
165       }
166       memp->next = NULL;
167       memp = m;
168     } else {
169       memp_tab[i] = NULL;
170     }
171   }
172
173 #ifndef SYS_LIGHTWEIGHT_PROT
174   mutex = sys_sem_new(1);
175 #endif
176
177   
178 }
179 /*-----------------------------------------------------------------------------------*/
180 void *
181 memp_malloc(memp_t type)
182 {
183   struct memp *memp;
184   void *mem;
185  
186   LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
187
188   memp = memp_tab[type];
189   
190   if(memp != NULL) {    
191     memp_tab[type] = memp->next;    
192     memp->next = NULL;
193 #ifdef MEMP_STATS
194     ++lwip_stats.memp[type].used;
195     if(lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
196       lwip_stats.memp[type].max = lwip_stats.memp[type].used;
197     }
198 #endif /* MEMP_STATS */
199     LWIP_ASSERT("memp_malloc: memp properly aligned",
200            ((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
201
202     mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
203     /* initialize memp memory with zeroes */
204     memset(mem, 0, memp_sizes[type]);   
205     return mem;
206   } else {
207     DEBUGF(MEMP_DEBUG, ("memp_malloc: out of memory in pool %d\n", type));
208 #ifdef MEMP_STATS
209     ++lwip_stats.memp[type].err;
210 #endif /* MEMP_STATS */
211     return NULL;
212   }
213 }
214 /*-----------------------------------------------------------------------------------*/
215 void *
216 memp_mallocp(memp_t type)
217 {
218   void *mem;
219 #ifdef SYS_LIGHTWEIGHT_PROT
220   SYS_ARCH_DECL_PROTECT(old_level);
221   SYS_ARCH_PROTECT(old_level);
222 #else /* SYS_LIGHTWEIGHT_PROT */  
223   sys_sem_wait(mutex);
224 #endif /* SYS_LIGHTWEIGHT_PROT */  
225
226   mem = memp_malloc(type);
227
228 #ifdef SYS_LIGHTWEIGHT_PROT
229   SYS_ARCH_UNPROTECT(old_level);
230 #else /* SYS_LIGHTWEIGHT_PROT */
231   sys_sem_signal(mutex);
232 #endif /* SYS_LIGHTWEIGHT_PROT */  
233   return mem;
234 }
235 /*-----------------------------------------------------------------------------------*/
236 void
237 memp_free(memp_t type, void *mem)
238 {
239   struct memp *memp;
240
241   if(mem == NULL) {
242     return;
243   }
244   memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
245
246 #ifdef MEMP_STATS
247   lwip_stats.memp[type].used--; 
248 #endif /* MEMP_STATS */
249   
250   memp->next = memp_tab[type]; 
251   memp_tab[type] = memp;
252
253   LWIP_ASSERT("memp sanity", memp_sanity());
254
255   return;
256 }
257 /*-----------------------------------------------------------------------------------*/
258 void 
259 memp_freep(memp_t type, void *mem)
260 {
261 #ifdef SYS_LIGHTWEIGHT_PROT
262     SYS_ARCH_DECL_PROTECT(old_level);
263     SYS_ARCH_PROTECT(old_level);
264 #else /* SYS_LIGHTWEIGHT_PROT */  
265   sys_sem_wait(mutex);
266 #endif /* SYS_LIGHTWEIGHT_PROT */  
267
268   memp_free(type, mem);
269
270 #ifdef SYS_LIGHTWEIGHT_PROT
271   SYS_ARCH_UNPROTECT(old_level);
272 #else /* SYS_LIGHTWEIGHT_PROT */
273   sys_sem_signal(mutex);
274 #endif /* SYS_LIGHTWEIGHT_PROT */  
275
276 }
277 /*-----------------------------------------------------------------------------------*/