2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
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.
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
27 * This file is part of the lwIP TCP/IP stack.
29 * Author: Adam Dunkels <adam@sics.se>
35 #include "lwip/memp.h"
37 #include "lwip/pbuf.h"
42 #include "lwip/api_msg.h"
43 #include "lwip/tcpip.h"
46 #include "lwip/stats.h"
54 static struct memp
*memp_tab
[MEMP_MAX
];
56 static const u16_t memp_sizes
[MEMP_MAX
] = {
58 sizeof(struct raw_pcb
),
59 sizeof(struct udp_pcb
),
60 sizeof(struct tcp_pcb
),
61 sizeof(struct tcp_pcb_listen
),
62 sizeof(struct tcp_seg
),
63 sizeof(struct netbuf
),
64 sizeof(struct netconn
),
65 sizeof(struct api_msg
),
66 sizeof(struct net_msg
),
67 sizeof(struct sys_timeout
)
70 static const u16_t memp_num
[MEMP_MAX
] = {
75 MEMP_NUM_TCP_PCB_LISTEN
,
84 static u8_t memp_memory
[(MEMP_NUM_PBUF
*
85 MEM_ALIGN_SIZE(sizeof(struct pbuf
) +
86 sizeof(struct memp
)) +
88 MEM_ALIGN_SIZE(sizeof(struct raw_pcb
) +
89 sizeof(struct memp
)) +
91 MEM_ALIGN_SIZE(sizeof(struct udp_pcb
) +
92 sizeof(struct memp
)) +
94 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb
) +
95 sizeof(struct memp
)) +
96 MEMP_NUM_TCP_PCB_LISTEN
*
97 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen
) +
98 sizeof(struct memp
)) +
100 MEM_ALIGN_SIZE(sizeof(struct tcp_seg
) +
101 sizeof(struct memp
)) +
103 MEM_ALIGN_SIZE(sizeof(struct netbuf
) +
104 sizeof(struct memp
)) +
106 MEM_ALIGN_SIZE(sizeof(struct netconn
) +
107 sizeof(struct memp
)) +
109 MEM_ALIGN_SIZE(sizeof(struct api_msg
) +
110 sizeof(struct memp
)) +
112 MEM_ALIGN_SIZE(sizeof(struct net_msg
) +
113 sizeof(struct memp
)) +
114 MEMP_NUM_SYS_TIMEOUT
*
115 MEM_ALIGN_SIZE(sizeof(struct sys_timeout
) +
116 sizeof(struct memp
)))];
119 #if !SYS_LIGHTWEIGHT_PROT
120 static sys_sem mutex
;
123 #if MEMP_SANITY_CHECK
130 for(i
= 0; i
< MEMP_MAX
; i
++) {
131 for(m
= memp_tab
[i
]; m
!= NULL
; m
= m
->next
) {
133 for(n
= memp_tab
[i
]; n
!= NULL
; n
= n
->next
) {
137 if (c
< 0) return 0; /* LW was: abort(); */
143 #endif /* MEMP_SANITY_CHECK*/
148 struct memp
*m
, *memp
;
153 for(i
= 0; i
< MEMP_MAX
; ++i
) {
154 lwip_stats
.memp
[i
].used
= lwip_stats
.memp
[i
].max
=
155 lwip_stats
.memp
[i
].err
= 0;
156 lwip_stats
.memp
[i
].avail
= memp_num
[i
];
158 #endif /* MEMP_STATS */
160 memp
= (struct memp
*)&memp_memory
[0];
161 for(i
= 0; i
< MEMP_MAX
; ++i
) {
162 size
= MEM_ALIGN_SIZE(memp_sizes
[i
] + sizeof(struct memp
));
163 if (memp_num
[i
] > 0) {
167 for(j
= 0; j
< memp_num
[i
]; ++j
) {
168 m
->next
= (struct memp
*)MEM_ALIGN((u8_t
*)m
+ size
);
179 #if !SYS_LIGHTWEIGHT_PROT
180 LWP_SemInit(&mutex
,1,1);
187 memp_malloc(memp_t type
)
191 #if SYS_LIGHTWEIGHT_PROT
192 SYS_ARCH_DECL_PROTECT(old_level
);
195 LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type
< MEMP_MAX
);
197 #if SYS_LIGHTWEIGHT_PROT
198 SYS_ARCH_PROTECT(old_level
);
199 #else /* SYS_LIGHTWEIGHT_PROT */
201 #endif /* SYS_LIGHTWEIGHT_PROT */
203 memp
= memp_tab
[type
];
205 memp_tab
[type
] = memp
->next
;
208 ++lwip_stats
.memp
[type
].used
;
209 if (lwip_stats
.memp
[type
].used
> lwip_stats
.memp
[type
].max
) {
210 lwip_stats
.memp
[type
].max
= lwip_stats
.memp
[type
].used
;
212 #endif /* MEMP_STATS */
213 #if SYS_LIGHTWEIGHT_PROT
214 SYS_ARCH_UNPROTECT(old_level
);
215 #else /* SYS_LIGHTWEIGHT_PROT */
217 #endif /* SYS_LIGHTWEIGHT_PROT */
218 LWIP_ASSERT("memp_malloc: memp properly aligned",
219 ((mem_ptr_t
)MEM_ALIGN((u8_t
*)memp
+ sizeof(struct memp
)) % MEM_ALIGNMENT
) == 0);
221 mem
= MEM_ALIGN((u8_t
*)memp
+ sizeof(struct memp
));
224 LWIP_DEBUGF(MEMP_DEBUG
| 2, ("memp_malloc: out of memory in pool %"S16_F
"\n", type
));
226 ++lwip_stats
.memp
[type
].err
;
227 #endif /* MEMP_STATS */
228 #if SYS_LIGHTWEIGHT_PROT
229 SYS_ARCH_UNPROTECT(old_level
);
230 #else /* SYS_LIGHTWEIGHT_PROT */
232 #endif /* SYS_LIGHTWEIGHT_PROT */
238 memp_free(memp_t type
, void *mem
)
241 #if SYS_LIGHTWEIGHT_PROT
242 SYS_ARCH_DECL_PROTECT(old_level
);
243 #endif /* SYS_LIGHTWEIGHT_PROT */
248 memp
= (struct memp
*)((u8_t
*)mem
- sizeof(struct memp
));
250 #if SYS_LIGHTWEIGHT_PROT
251 SYS_ARCH_PROTECT(old_level
);
252 #else /* SYS_LIGHTWEIGHT_PROT */
254 #endif /* SYS_LIGHTWEIGHT_PROT */
257 lwip_stats
.memp
[type
].used
--;
258 #endif /* MEMP_STATS */
260 memp
->next
= memp_tab
[type
];
261 memp_tab
[type
] = memp
;
263 #if MEMP_SANITY_CHECK
264 LWIP_ASSERT("memp sanity", memp_sanity());
267 #if SYS_LIGHTWEIGHT_PROT
268 SYS_ARCH_UNPROTECT(old_level
);
269 #else /* SYS_LIGHTWEIGHT_PROT */
271 #endif /* SYS_LIGHTWEIGHT_PROT */