00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "lwip/opt.h"
00040
00041 #include "lwip/memp.h"
00042
00043 #include "lwip/pbuf.h"
00044 #include "lwip/udp.h"
00045 #include "lwip/tcp.h"
00046 #include "lwip/api.h"
00047 #include "lwip/api_msg.h"
00048 #include "lwip/tcpip.h"
00049
00050 #include "lwip/sys.h"
00051 #include "lwip/stats.h"
00052
00053 struct memp {
00054 struct memp *next;
00055 };
00056
00057
00058
00059 static struct memp *memp_tab[MEMP_MAX];
00060
00061 static const u16_t memp_sizes[MEMP_MAX] = {
00062 sizeof(struct pbuf),
00063 sizeof(struct udp_pcb),
00064 sizeof(struct tcp_pcb),
00065 sizeof(struct tcp_pcb_listen),
00066 sizeof(struct tcp_seg),
00067 sizeof(struct netbuf),
00068 sizeof(struct netconn),
00069 sizeof(struct api_msg),
00070 sizeof(struct tcpip_msg)
00071 };
00072
00073 static const u16_t memp_num[MEMP_MAX] = {
00074 MEMP_NUM_PBUF,
00075 MEMP_NUM_UDP_PCB,
00076 MEMP_NUM_TCP_PCB,
00077 MEMP_NUM_TCP_PCB_LISTEN,
00078 MEMP_NUM_TCP_SEG,
00079 MEMP_NUM_NETBUF,
00080 MEMP_NUM_NETCONN,
00081 MEMP_NUM_API_MSG,
00082 MEMP_NUM_TCPIP_MSG
00083 };
00084
00085 static u8_t memp_memory[(MEMP_NUM_PBUF *
00086 MEM_ALIGN_SIZE(sizeof(struct pbuf) +
00087 sizeof(struct memp)) +
00088 MEMP_NUM_UDP_PCB *
00089 MEM_ALIGN_SIZE(sizeof(struct udp_pcb) +
00090 sizeof(struct memp)) +
00091 MEMP_NUM_TCP_PCB *
00092 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb) +
00093 sizeof(struct memp)) +
00094 MEMP_NUM_TCP_PCB_LISTEN *
00095 MEM_ALIGN_SIZE(sizeof(struct tcp_pcb_listen) +
00096 sizeof(struct memp)) +
00097 MEMP_NUM_TCP_SEG *
00098 MEM_ALIGN_SIZE(sizeof(struct tcp_seg) +
00099 sizeof(struct memp)) +
00100 MEMP_NUM_NETBUF *
00101 MEM_ALIGN_SIZE(sizeof(struct netbuf) +
00102 sizeof(struct memp)) +
00103 MEMP_NUM_NETCONN *
00104 MEM_ALIGN_SIZE(sizeof(struct netconn) +
00105 sizeof(struct memp)) +
00106 MEMP_NUM_API_MSG *
00107 MEM_ALIGN_SIZE(sizeof(struct api_msg) +
00108 sizeof(struct memp)) +
00109 MEMP_NUM_TCPIP_MSG *
00110 MEM_ALIGN_SIZE(sizeof(struct tcpip_msg) +
00111 sizeof(struct memp)))];
00112
00113
00114 #if !SYS_LIGHTWEIGHT_PROT
00115 static sys_sem_t mutex;
00116 #endif
00117
00118 #ifdef LWIP_DEBUG
00119 static int
00120 memp_sanity(void)
00121 {
00122 int i, c;
00123 struct memp *m, *n;
00124
00125 for(i = 0; i < MEMP_MAX; i++) {
00126 for(m = memp_tab[i]; m != NULL; m = m->next) {
00127 c = 1;
00128 for(n = memp_tab[i]; n != NULL; n = n->next) {
00129 if(n == m) {
00130 --c;
00131 }
00132 if(c < 0) return 0;
00133 }
00134 }
00135 }
00136 return 1;
00137 }
00138 #endif
00139
00140 void
00141 memp_init(void)
00142 {
00143 struct memp *m, *memp;
00144 u16_t i, j;
00145 u16_t size;
00146
00147 #ifdef MEMP_STATS
00148 for(i = 0; i < MEMP_MAX; ++i) {
00149 lwip_stats.memp[i].used = lwip_stats.memp[i].max =
00150 lwip_stats.memp[i].err = 0;
00151 lwip_stats.memp[i].avail = memp_num[i];
00152 }
00153 #endif
00154
00155 memp = (struct memp *)&memp_memory[0];
00156 for(i = 0; i < MEMP_MAX; ++i) {
00157 size = MEM_ALIGN_SIZE(memp_sizes[i] + sizeof(struct memp));
00158 if(memp_num[i] > 0) {
00159 memp_tab[i] = memp;
00160 m = memp;
00161
00162 for(j = 0; j < memp_num[i]; ++j) {
00163 m->next = (struct memp *)MEM_ALIGN((u8_t *)m + size);
00164 memp = m;
00165 m = m->next;
00166 }
00167 memp->next = NULL;
00168 memp = m;
00169 } else {
00170 memp_tab[i] = NULL;
00171 }
00172 }
00173
00174 #if !SYS_LIGHTWEIGHT_PROT
00175 mutex = sys_sem_new(1);
00176 #endif
00177
00178
00179 }
00180
00181 void *
00182 memp_malloc(memp_t type)
00183 {
00184 struct memp *memp;
00185 void *mem;
00186
00187 LWIP_ASSERT("memp_malloc: type < MEMP_MAX", type < MEMP_MAX);
00188
00189 memp = memp_tab[type];
00190
00191 if(memp != NULL) {
00192 memp_tab[type] = memp->next;
00193 memp->next = NULL;
00194 #ifdef MEMP_STATS
00195 ++lwip_stats.memp[type].used;
00196 if(lwip_stats.memp[type].used > lwip_stats.memp[type].max) {
00197 lwip_stats.memp[type].max = lwip_stats.memp[type].used;
00198 }
00199 #endif
00200 LWIP_ASSERT("memp_malloc: memp properly aligned",
00201 ((u32_t)MEM_ALIGN((u8_t *)memp + sizeof(struct memp)) % MEM_ALIGNMENT) == 0);
00202
00203 mem = MEM_ALIGN((u8_t *)memp + sizeof(struct memp));
00204
00205 memset(mem, 0, memp_sizes[type]);
00206 return mem;
00207 } else {
00208 DEBUGF(MEMP_DEBUG | 2, ("memp_malloc: out of memory in pool %d\n", type));
00209 #ifdef MEMP_STATS
00210 ++lwip_stats.memp[type].err;
00211 #endif
00212 return NULL;
00213 }
00214 }
00215
00216 void *
00217 memp_mallocp(memp_t type)
00218 {
00219 void *mem;
00220 #if SYS_LIGHTWEIGHT_PROT
00221 SYS_ARCH_DECL_PROTECT(old_level);
00222 SYS_ARCH_PROTECT(old_level);
00223 #else
00224 sys_sem_wait(mutex);
00225 #endif
00226
00227 mem = memp_malloc(type);
00228
00229 #if SYS_LIGHTWEIGHT_PROT
00230 SYS_ARCH_UNPROTECT(old_level);
00231 #else
00232 sys_sem_signal(mutex);
00233 #endif
00234 return mem;
00235 }
00236
00237 void
00238 memp_free(memp_t type, void *mem)
00239 {
00240 struct memp *memp;
00241
00242 if(mem == NULL) {
00243 return;
00244 }
00245 memp = (struct memp *)((u8_t *)mem - sizeof(struct memp));
00246
00247 #ifdef MEMP_STATS
00248 lwip_stats.memp[type].used--;
00249 #endif
00250
00251 memp->next = memp_tab[type];
00252 memp_tab[type] = memp;
00253
00254 LWIP_ASSERT("memp sanity", memp_sanity());
00255
00256 return;
00257 }
00258
00259 void
00260 memp_freep(memp_t type, void *mem)
00261 {
00262 #if SYS_LIGHTWEIGHT_PROT
00263 SYS_ARCH_DECL_PROTECT(old_level);
00264 SYS_ARCH_PROTECT(old_level);
00265 #else
00266 sys_sem_wait(mutex);
00267 #endif
00268
00269 memp_free(type, mem);
00270
00271 #if SYS_LIGHTWEIGHT_PROT
00272 SYS_ARCH_UNPROTECT(old_level);
00273 #else
00274 sys_sem_signal(mutex);
00275 #endif
00276
00277 }
00278