pbuf_free_safe() would be enough in this situation, but since memp_free
is the problem (no pbuf_free()),
I think memp_free_safe() would be better since it is more generic.
mem_free_safe could do the trick but only when paired with a mem_malloc_safe. Or you have another idea with mem_free_safe.
I like your idea of putting a list of must_be_freed buffer.
We could have a lock variable that is set in mem_malloc
void mem_malloc()
{
//Acquire Lock
mem_lock = 1;
//Do all the allocating stuff
//Release Lock
mem_lock = 0;
}
in mem_free()
{
if(mem_lock == 1)
{
//Put buffer on the must_be_freed list for later processing (mem_free_list)
}
else
{
//Continue the free process
//And also free other item in the must_be_freed list
mem_free_list()
}
}
We could then process list in another portion of the stack and why not in mem_malloc.
As a side note, this kind of functionality (list access) could be achieved with some Atomic primitives (InterlockedCompareExchange, AtomicCompareExchange). I our code we use often this kind of functions. This could be interesting to provide some macro, that could be redefined to meet each platform.
A basic implementation (compatible with all platforms) would be
typedef u32_t uDef_t; //Default architecture unsigned value (here, 32 bits processor => 32 bits unsigned value)
uDef_t AtomicCompareExchange(uDef_t* Address, uDef_t Comparand, uDef_t NewVal)
{
uDef_t OldValue;
SYS_ARCH_DECL_PROTECT(old_level);
old_level = SYS_ARCH_PROTECT();
if((OldValue = *Address) == Comparand){
*Address = NewVal;
}
SYS_ARCH_UNPROTECT(old_level);
return OldValue;
}
In a win32 system this would be the InterlockedCompareExchange function, in a PowerPC platform this would be a function using atomic primitives functionnalities.
Fred