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"
52 #define MEMP_SIZE MEM_ALIGN_SIZE(sizeof(struct memp))
54 static struct memp
*memp_tab
[MEMP_MAX
];
56 static const u16_t memp_sizes
[MEMP_MAX
] = {
57 MEM_ALIGN_SIZE(sizeof(struct pbuf
)),
58 MEM_ALIGN_SIZE(sizeof(struct raw_pcb
)),
59 MEM_ALIGN_SIZE(sizeof(struct udp_pcb
)),
60 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb
)),
61 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen
)),
62 MEM_ALIGN_SIZE(sizeof(struct tcp_seg
)),
63 MEM_ALIGN_SIZE(sizeof(struct netbuf
)),
64 MEM_ALIGN_SIZE(sizeof(struct netconn
)),
65 MEM_ALIGN_SIZE(sizeof(struct api_msg
)),
66 MEM_ALIGN_SIZE(sizeof(struct tcpip_msg
)),
67 MEM_ALIGN_SIZE(sizeof(struct sys_timeo
))
70 static const u16_t memp_num
[MEMP_MAX
] = {
75 MEMP_NUM_TCP_PCB_LISTEN
,
84 #define MEMP_TYPE_SIZE(qty, type) \
85 ((qty) * (MEMP_SIZE + MEM_ALIGN_SIZE(sizeof(type))))
87 static u8_t memp_memory
[MEM_ALIGNMENT
- 1 +
88 MEMP_TYPE_SIZE(MEMP_NUM_PBUF
, struct pbuf
) +
89 MEMP_TYPE_SIZE(MEMP_NUM_RAW_PCB
, struct raw_pcb
) +
90 MEMP_TYPE_SIZE(MEMP_NUM_UDP_PCB
, struct udp_pcb
) +
91 MEMP_TYPE_SIZE(MEMP_NUM_TCP_PCB
, struct tcp_pcb
) +
92 MEMP_TYPE_SIZE(MEMP_NUM_TCP_PCB_LISTEN
, struct tcp_pcb_listen
) +
93 MEMP_TYPE_SIZE(MEMP_NUM_TCP_SEG
, struct tcp_seg
) +
94 MEMP_TYPE_SIZE(MEMP_NUM_NETBUF
, struct netbuf
) +
95 MEMP_TYPE_SIZE(MEMP_NUM_NETCONN
, struct netconn
) +
96 MEMP_TYPE_SIZE(MEMP_NUM_API_MSG
, struct api_msg
) +
97 MEMP_TYPE_SIZE(MEMP_NUM_TCPIP_MSG
, struct tcpip_msg
) +
98 MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT
, struct sys_timeo
)];
100 #if !SYS_LIGHTWEIGHT_PROT
101 static sys_sem_t mutex
;
104 #if MEMP_SANITY_CHECK
111 for (i
= 0; i
< MEMP_MAX
; i
++) {
112 for (m
= memp_tab
[i
]; m
!= NULL
; m
= m
->next
) {
114 for (n
= memp_tab
[i
]; n
!= NULL
; n
= n
->next
) {
115 if (n
== m
&& --c
< 0) {
116 return 0; /* LW was: abort(); */
123 #endif /* MEMP_SANITY_CHECK*/
132 for (i
= 0; i
< MEMP_MAX
; ++i
) {
133 lwip_stats
.memp
[i
].used
= lwip_stats
.memp
[i
].max
=
134 lwip_stats
.memp
[i
].err
= 0;
135 lwip_stats
.memp
[i
].avail
= memp_num
[i
];
137 #endif /* MEMP_STATS */
139 memp
= MEM_ALIGN(memp_memory
);
140 for (i
= 0; i
< MEMP_MAX
; ++i
) {
142 for (j
= 0; j
< memp_num
[i
]; ++j
) {
143 memp
->next
= memp_tab
[i
];
145 memp
= (struct memp
*)((u8_t
*)memp
+ MEMP_SIZE
+ memp_sizes
[i
]);
149 #if !SYS_LIGHTWEIGHT_PROT
150 mutex
= sys_sem_new(1);
155 memp_malloc(memp_t type
)
159 #if SYS_LIGHTWEIGHT_PROT
160 SYS_ARCH_DECL_PROTECT(old_level
);
163 LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type
< MEMP_MAX
);
165 #if SYS_LIGHTWEIGHT_PROT
166 SYS_ARCH_PROTECT(old_level
);
167 #else /* SYS_LIGHTWEIGHT_PROT */
169 #endif /* SYS_LIGHTWEIGHT_PROT */
171 memp
= memp_tab
[type
];
174 memp_tab
[type
] = memp
->next
;
177 ++lwip_stats
.memp
[type
].used
;
178 if (lwip_stats
.memp
[type
].used
> lwip_stats
.memp
[type
].max
) {
179 lwip_stats
.memp
[type
].max
= lwip_stats
.memp
[type
].used
;
181 #endif /* MEMP_STATS */
182 mem
= (u8_t
*)memp
+ MEMP_SIZE
;
183 LWIP_ASSERT("memp_malloc: memp properly aligned",
184 ((mem_ptr_t
)memp
% MEM_ALIGNMENT
) == 0);
186 LWIP_DEBUGF(MEMP_DEBUG
| 2, ("memp_malloc: out of memory in pool %"S16_F
"\n", type
));
188 ++lwip_stats
.memp
[type
].err
;
189 #endif /* MEMP_STATS */
193 #if SYS_LIGHTWEIGHT_PROT
194 SYS_ARCH_UNPROTECT(old_level
);
195 #else /* SYS_LIGHTWEIGHT_PROT */
196 sys_sem_signal(mutex
);
197 #endif /* SYS_LIGHTWEIGHT_PROT */
203 memp_free(memp_t type
, void *mem
)
206 #if SYS_LIGHTWEIGHT_PROT
207 SYS_ARCH_DECL_PROTECT(old_level
);
208 #endif /* SYS_LIGHTWEIGHT_PROT */
214 memp
= (struct memp
*)((u8_t
*)mem
- MEMP_SIZE
);
216 #if SYS_LIGHTWEIGHT_PROT
217 SYS_ARCH_PROTECT(old_level
);
218 #else /* SYS_LIGHTWEIGHT_PROT */
220 #endif /* SYS_LIGHTWEIGHT_PROT */
223 lwip_stats
.memp
[type
].used
--;
224 #endif /* MEMP_STATS */
226 memp
->next
= memp_tab
[type
];
227 memp_tab
[type
] = memp
;
229 #if MEMP_SANITY_CHECK
230 LWIP_ASSERT("memp sanity", memp_sanity());
233 #if SYS_LIGHTWEIGHT_PROT
234 SYS_ARCH_UNPROTECT(old_level
);
235 #else /* SYS_LIGHTWEIGHT_PROT */
236 sys_sem_signal(mutex
);
237 #endif /* SYS_LIGHTWEIGHT_PROT */