lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] Re: [lwip] questions & suggestions


From: Adam Dunkels
Subject: [lwip-users] Re: [lwip] questions & suggestions
Date: Wed, 08 Jan 2003 23:26:00 -0000

Hi Adel!

On Tuesday 11 December 2001 16:53, you wrote:
> You don't use a semaphore for memory allocation in the pbuf_alloc()
> function for mem, memp and pbuf memory pools. Is it rigth? What if several
> tasks use this function concurently?

This is one of the things that was flawed in 0.4.x and are to be fixed before 
the 0.5 can be released. Thanks for pointing this out, though. The 
mem_malloc()/mem_free() calls are already protected with a semaphore, but the 
memp stuff and the pbuf pool allocation is slightly broken. The memp 
allocation is simple to fix: just add a "p" to the memp_malloc() and 
memp_free() calls. memp_mallocp() and memp_freep() are the protected 
equivalents of memp_malloc() and memp_free(). 

The pbuf pool allocation needs a little more thought, however. The problem is 
this:

Device drivers call pbuf_alloc() asking for PBUF_POOL buffers. Since the 
allocation must be done quickly (this might even be called in an interrupt 
handler) no semaphores or any other IPC can be used. Still, the list of free 
pbufs must be protected. 

The assumption that many threads can be in pbuf_free(), but only one thread 
in pbuf_alloc(PBUF_POOL) makes it possible to solve this problem without 
having to use semaphore waiting in pbuf_alloc().

So instead of using just one list for free pbufs, three lists are used. One 
list (pbuf_pool_alloc_cache) is used only within pbuf_alloc() for caching 
buffers that was deallocated during a previous allocation. Since this list is 
used by only one thread, it doesn't have to be protected. The second list, 
pbuf_pool_free_cache, is used in pbuf_free() and pbuf_realloc() to store 
buffers that are in the process of being freed. This list is protected by a 
semaphore.

The third list, pbuf_pool, is shared between pbuf_alloc() and pbuf_free(). 
This list is used to pass free buffers from pbuf_free() to pbuf_alloc(). The 
list is protected by both a semaphore and two variables. The semaphore is 
needed to prevent multiple threads from being in pbuf_free() at the same time 
but is not used by pbuf_alloc(). Instead, the two variables 
pbuf_pool_free_lock and pbuf_pool_alloc_lock are used to prevent pbuf_alloc() 
from accessing the list when it is updated by pbuf_free() in the following 
way:

pbuf_alloc() {
  if(pbuf_pool_free_lock) return NULL;
  ++pbuf_pool_alloc_lock;
  if(!pbuf_pool_free_lock) /* Access pbuf_pool list. */
  --pbuf_poll_alloc_lock;
}

pbuf_free() {
  ++pbuf_pool_free_lock;
  if(!pbuf_pool_alloc_lock) /* Access list. */
  --pbuf_pool_free_lock;
}

Since buffers are not guaranteed to be moved from the pbuf_pool_free_cache to 
the pbuf_pool list during a pbuf_free(), the new function pbuf_refresh() must 
be called now and then (pbuf_free() does call it every time). Currently, this 
is done in pbuf_free() and pbuf_realloc(), but perhaps a periodic timer 
should be used for this? What do you think?

/adam
-- 
Adam Dunkels <address@hidden>
http://www.sics.se/~adam
[This message was sent through the lwip discussion list.]




reply via email to

[Prev in Thread] Current Thread [Next in Thread]