mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2025-04-01 13:20:45 +00:00
Added lightweight protection. In coldfire this is implemented by disabling
interrupts. In unixsim this is implemented by using a mutex. Uses #define SYS_LIGHTWEIGHT_PROT to enable. It is enabled in coldfire by default, but disabled in unixsim. Fixes bug 2005 if you enable SYS_LIGHTWEIGHT_PROT. So the bug is closed.
This commit is contained in:
parent
987e9df948
commit
98fbb855fb
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
@ -212,9 +212,19 @@ void *
|
||||
memp_mallocp(memp_t type)
|
||||
{
|
||||
void *mem;
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level = sys_arch_protect();
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_wait(mutex);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
mem = memp_malloc(type);
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_signal(mutex);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
return mem;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -243,8 +253,19 @@ memp_free(memp_t type, void *mem)
|
||||
void
|
||||
memp_freep(memp_t type, void *mem)
|
||||
{
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level = sys_arch_protect();
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_wait(mutex);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
memp_free(type, mem);
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_signal(mutex);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
147
src/core/pbuf.c
147
src/core/pbuf.c
@ -52,8 +52,12 @@
|
||||
#include "arch/perf.h"
|
||||
|
||||
static u8_t pbuf_pool_memory[(PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf)))];
|
||||
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock;
|
||||
static sys_sem_t pbuf_pool_free_sem;
|
||||
#endif
|
||||
|
||||
static struct pbuf *pbuf_pool = NULL;
|
||||
static struct pbuf *pbuf_pool_alloc_cache = NULL;
|
||||
static struct pbuf *pbuf_pool_free_cache = NULL;
|
||||
@ -99,10 +103,11 @@ pbuf_init(void)
|
||||
are no more pbufs in the pool. */
|
||||
q->next = NULL;
|
||||
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
pbuf_pool_alloc_lock = 0;
|
||||
pbuf_pool_free_lock = 0;
|
||||
pbuf_pool_free_sem = sys_sem_new(1);
|
||||
|
||||
#endif
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* The following two functions are only called from pbuf_alloc(). */
|
||||
@ -112,6 +117,12 @@ pbuf_pool_alloc(void)
|
||||
{
|
||||
struct pbuf *p = NULL;
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level;
|
||||
|
||||
old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
/* First, see if there are pbufs in the cache. */
|
||||
if(pbuf_pool_alloc_cache) {
|
||||
p = pbuf_pool_alloc_cache;
|
||||
@ -119,6 +130,7 @@ pbuf_pool_alloc(void)
|
||||
pbuf_pool_alloc_cache = p->next;
|
||||
}
|
||||
} else {
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
/* Next, check the actual pbuf pool, but if the pool is locked, we
|
||||
pretend to be out of buffers and return NULL. */
|
||||
if(pbuf_pool_free_lock) {
|
||||
@ -129,18 +141,21 @@ pbuf_pool_alloc(void)
|
||||
}
|
||||
pbuf_pool_alloc_lock = 1;
|
||||
if(!pbuf_pool_free_lock) {
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
p = pbuf_pool;
|
||||
if(p) {
|
||||
pbuf_pool = p->next;
|
||||
}
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
#ifdef PBUF_STATS
|
||||
} else {
|
||||
++lwip_stats.pbuf.alloc_locked;
|
||||
#endif /* PBUF_STATS */
|
||||
}
|
||||
pbuf_pool_alloc_lock = 0;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
|
||||
|
||||
#ifdef PBUF_STATS
|
||||
if(p != NULL) {
|
||||
++lwip_stats.pbuf.used;
|
||||
@ -150,6 +165,10 @@ pbuf_pool_alloc(void)
|
||||
}
|
||||
#endif /* PBUF_STATS */
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
return p;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
@ -157,19 +176,33 @@ static void
|
||||
pbuf_pool_free(struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
#ifdef PBUF_STATS
|
||||
for(q = p; q != NULL; q = q->next) {
|
||||
--lwip_stats.pbuf.used;
|
||||
}
|
||||
#endif /* PBUF_STATS */
|
||||
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
if(pbuf_pool_alloc_cache == NULL) {
|
||||
pbuf_pool_alloc_cache = p;
|
||||
} else {
|
||||
for(q = pbuf_pool_alloc_cache; q->next != NULL; q = q->next);
|
||||
q->next = p;
|
||||
}
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* pbuf_alloc():
|
||||
@ -313,12 +346,19 @@ void
|
||||
pbuf_refresh(void)
|
||||
{
|
||||
struct pbuf *p;
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level;
|
||||
|
||||
old_level = sys_arch_protect();
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_wait(pbuf_pool_free_sem);
|
||||
#endif /* else SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
if(pbuf_pool_free_cache != NULL) {
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
pbuf_pool_free_lock = 1;
|
||||
if(!pbuf_pool_alloc_lock) {
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
if(pbuf_pool == NULL) {
|
||||
pbuf_pool = pbuf_pool_free_cache;
|
||||
} else {
|
||||
@ -326,23 +366,48 @@ pbuf_refresh(void)
|
||||
p->next = pbuf_pool_free_cache;
|
||||
}
|
||||
pbuf_pool_free_cache = NULL;
|
||||
#ifndef SYS_LIGHTWEIGHT_PROT
|
||||
#ifdef PBUF_STATS
|
||||
} else {
|
||||
++lwip_stats.pbuf.refresh_locked;
|
||||
#endif /* PBUF_STATS */
|
||||
}
|
||||
|
||||
pbuf_pool_free_lock = 0;
|
||||
pbuf_pool_free_lock = 0;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
sys_sem_signal(pbuf_pool_free_sem);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
#define PBUF_POOL_FREE(p) do { \
|
||||
sys_sem_wait(pbuf_pool_free_sem); \
|
||||
p->next = pbuf_pool_free_cache; \
|
||||
pbuf_pool_free_cache = p; \
|
||||
sys_sem_signal(pbuf_pool_free_sem); \
|
||||
|
||||
#ifdef PBUF_STATS
|
||||
#define DEC_PBUF_STATS do { --lwip_stats.pbuf.used; } while (0)
|
||||
#else /* PBUF_STATS */
|
||||
#define DEC_PBUF_STATS
|
||||
#endif /* PBUF_STATS */
|
||||
|
||||
#define PBUF_POOL_FAST_FREE(p) do { \
|
||||
p->next = pbuf_pool_free_cache; \
|
||||
pbuf_pool_free_cache = p; \
|
||||
DEC_PBUF_STATS; \
|
||||
} while (0)
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
#define PBUF_POOL_FREE(p) do { \
|
||||
u32_t old_level = sys_arch_protect(); \
|
||||
PBUF_POOL_FAST_FREE(p); \
|
||||
sys_arch_unprotect(old_level); \
|
||||
} while(0)
|
||||
#else /* SYS_LIGHTWEIGHT_PROT */
|
||||
#define PBUF_POOL_FREE(p) do { \
|
||||
sys_sem_wait(pbuf_pool_free_sem); \
|
||||
PBUF_POOL_FAST_FREE(p); \
|
||||
sys_sem_signal(pbuf_pool_free_sem); \
|
||||
} while(0)
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* pbuf_realloc:
|
||||
*
|
||||
@ -389,9 +454,6 @@ pbuf_realloc(struct pbuf *p, u16_t size)
|
||||
while(q != NULL) {
|
||||
r = q->next;
|
||||
PBUF_POOL_FREE(q);
|
||||
#ifdef PBUF_STATS
|
||||
--lwip_stats.pbuf.used;
|
||||
#endif /* PBUF_STATS */
|
||||
q = r;
|
||||
}
|
||||
break;
|
||||
@ -477,7 +539,10 @@ pbuf_free(struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q;
|
||||
u8_t count = 0;
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
if(p == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -489,14 +554,23 @@ pbuf_free(struct pbuf *p)
|
||||
p->flags == PBUF_FLAG_RAM);
|
||||
|
||||
ASSERT("pbuf_free: p->ref > 0", p->ref > 0);
|
||||
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
/* Since decrementing ref cannot be guarranteed to be a single machine operation
|
||||
we must protect it. Also, the later test of ref must be protected.
|
||||
*/
|
||||
old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
/* Decrement reference count. */
|
||||
p->ref--;
|
||||
|
||||
q = NULL;
|
||||
/* If reference count == 0, actually deallocate pbuf. */
|
||||
if(p->ref == 0) {
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif
|
||||
|
||||
while(p != NULL) {
|
||||
/* Check if this is a pbuf from the pool. */
|
||||
if(p->flags == PBUF_FLAG_POOL) {
|
||||
@ -504,21 +578,25 @@ pbuf_free(struct pbuf *p)
|
||||
p->payload = (void *)((u8_t *)p + sizeof(struct pbuf));
|
||||
q = p->next;
|
||||
PBUF_POOL_FREE(p);
|
||||
#ifdef PBUF_STATS
|
||||
--lwip_stats.pbuf.used;
|
||||
#endif /* PBUF_STATS */
|
||||
} else if(p->flags == PBUF_FLAG_ROM) {
|
||||
q = p->next;
|
||||
memp_freep(MEMP_PBUF, p);
|
||||
} else {
|
||||
q = p->next;
|
||||
mem_free(p);
|
||||
if(p->flags == PBUF_FLAG_ROM) {
|
||||
q = p->next;
|
||||
memp_freep(MEMP_PBUF, p);
|
||||
} else {
|
||||
q = p->next;
|
||||
mem_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
p = q;
|
||||
++count;
|
||||
}
|
||||
pbuf_refresh();
|
||||
}
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
else
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
PERF_STOP("pbuf_free");
|
||||
|
||||
@ -553,10 +631,21 @@ pbuf_clen(struct pbuf *p)
|
||||
void
|
||||
pbuf_ref(struct pbuf *p)
|
||||
{
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
if(p == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
++(p->ref);
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------*/
|
||||
@ -567,10 +656,18 @@ pbuf_ref(struct pbuf *p)
|
||||
void
|
||||
pbuf_ref_chain(struct pbuf *p)
|
||||
{
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
u32_t old_level = sys_arch_protect();
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
while (p != NULL) {
|
||||
p->ref++;
|
||||
p=p->next;
|
||||
}
|
||||
|
||||
#ifdef SYS_LIGHTWEIGHT_PROT
|
||||
sys_arch_unprotect(old_level);
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* pbuf_chain():
|
||||
@ -665,5 +762,3 @@ pbuf_unref(struct pbuf *f)
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,6 +103,14 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout);
|
||||
void sys_mbox_free(sys_mbox_t mbox);
|
||||
void sys_mbox_fetch(sys_mbox_t mbox, void **msg);
|
||||
|
||||
/* Critical Region Protection */
|
||||
/* These functions must be implemented in the sys_arch.c file.
|
||||
In some implementations they can provide a more light-weight protection
|
||||
mechanism than using semaphores. Otherwise semaphores can be used for
|
||||
implementation */
|
||||
u32_t sys_arch_protect(void);
|
||||
void sys_arch_unprotect(u32_t pval);
|
||||
|
||||
/* Thread functions. */
|
||||
void sys_thread_new(void (* thread)(void *arg), void *arg);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user