1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/malloc_thread_safety: use mutex

Disabling IRQs during malloc() provides mutually exclusive access and even is
safe from IRQ context, but is suboptimal for real time scenarios. Instead, the
implementation is changed to use a mutex to provide mutually exclusive access.

As a result, calls to malloc() and free() from IRQ context no longer is
possible. But this this is a really horrible idea to begin with, the impact
should be minimal and the improved real time properties of the system should
make it a good trade-off. An assert() is added to allow easy detection of
regressions and, hence, aid users to fix their code.
This commit is contained in:
Marian Buschsieweke 2020-12-10 09:43:55 +01:00
parent 902aa29b62
commit c790e2eb6d
No known key found for this signature in database
GPG Key ID: 61F64C6599B1539F

View File

@ -14,41 +14,49 @@
* @author Gunar Schorcht <gunar@schorcht.net>
*/
#include "assert.h"
#include "irq.h"
#include "mutex.h"
extern void *__real_malloc(size_t size);
extern void __real_free(void *ptr);
extern void *__real_calloc(size_t nmemb, size_t size);
extern void *__real_realloc(void *ptr, size_t size);
static mutex_t _lock;
void *__wrap_malloc(size_t size)
{
unsigned state = irq_disable();
assert(!irq_is_in());
mutex_lock(&_lock);
void *ptr = __real_malloc(size);
irq_restore(state);
mutex_unlock(&_lock);
return ptr;
}
void __wrap_free(void *ptr)
{
unsigned state = irq_disable();
assert(!irq_is_in());
mutex_lock(&_lock);
__real_free(ptr);
irq_restore(state);
mutex_unlock(&_lock);
}
void *__wrap_calloc(size_t nmemb, size_t size)
{
unsigned state = irq_disable();
assert(!irq_is_in());
mutex_lock(&_lock);
void *ptr = __real_calloc(nmemb, size);
irq_restore(state);
mutex_unlock(&_lock);
return ptr;
}
void *__wrap_realloc(void *ptr, size_t size)
{
unsigned state = irq_disable();
assert(!irq_is_in());
mutex_lock(&_lock);
void *new = __real_realloc(ptr, size);
irq_restore(state);
mutex_unlock(&_lock);
return new;
}