feat: add mutex prio to prevent deadlock on mutex

This commit is contained in:
Nemo D'ACREMONT 2025-04-08 19:06:40 +02:00
parent 8d023ed201
commit 95457372b6
No known key found for this signature in database
GPG Key ID: 85F245EC3BB1E022

View File

@ -22,6 +22,7 @@
#define WAITED (1 << 3) #define WAITED (1 << 3)
#define MUTEX_WAITING (1 << 4) #define MUTEX_WAITING (1 << 4)
#define MUTEX_LOCKING (1 << 5) #define MUTEX_LOCKING (1 << 5)
#define MUTEX_MAXPRIO 5
#define IS_WAITED(entry) (HAS_STATUS(entry, WAITED)) #define IS_WAITED(entry) (HAS_STATUS(entry, WAITED))
#define IS_MUTEX_WAITING(entry) (HAS_STATUS(entry, MUTEX_WAITING)) #define IS_MUTEX_WAITING(entry) (HAS_STATUS(entry, MUTEX_WAITING))
@ -53,6 +54,7 @@ struct context_entry_t {
struct mutex_fifo_entry_t mutex_fifo_entry; struct mutex_fifo_entry_t mutex_fifo_entry;
int valgrind_id; int valgrind_id;
int status; int status;
int mutex_prio;
char stack[STACK_SIZE]; char stack[STACK_SIZE];
}; };
@ -86,9 +88,14 @@ int thread_yield(void)
} }
if (HAS_STATUS(running, MUTEX_LOCKING)) { if (HAS_STATUS(running, MUTEX_LOCKING)) {
if (running->mutex_prio > 0) {
running->mutex_prio--;
DBG("skip yield : running thread is locking a mutex"); DBG("skip yield : running thread is locking a mutex");
return 0; return 0;
} }
else
running->mutex_prio = MUTEX_MAXPRIO;
}
#ifdef FIBO_STRAT #ifdef FIBO_STRAT
if (!(IS_YIELD(running)) && !IS_FINISHED(running) && !IS_WAITING(running)) { if (!(IS_YIELD(running)) && !IS_FINISHED(running) && !IS_WAITING(running)) {
@ -167,6 +174,7 @@ int thread_create(thread_t* newthread, void* (*func)(void*), void* funcarg)
new_entry->status = ALLOCATED; new_entry->status = ALLOCATED;
new_entry->retvalue = NULL; new_entry->retvalue = NULL;
new_entry->last_waited = NULL; new_entry->last_waited = NULL;
new_entry->mutex_prio = MUTEX_MAXPRIO;
*newthread = new_entry; *newthread = new_entry;
@ -430,6 +438,7 @@ int thread_mutex_lock(thread_mutex_t* mutex)
thread_yield(); thread_yield();
} }
SET_STATUS(running, MUTEX_LOCKING); SET_STATUS(running, MUTEX_LOCKING);
running->mutex_prio = MUTEX_MAXPRIO;
mutex->dummy = 1; mutex->dummy = 1;
return 0; return 0;