fix: fix segfault on clearcontext + exit, status WAITED not removed correctly

This commit is contained in:
Nemo D'ACREMONT 2025-04-18 22:54:50 +02:00
parent 5632f46988
commit 6d57ce0c46
No known key found for this signature in database
GPG Key ID: 85F245EC3BB1E022
2 changed files with 23 additions and 15 deletions

View File

@ -215,9 +215,6 @@ int thread_join(thread_t thread, void** retval)
} while (!IS_FINISHED(entry)); } while (!IS_FINISHED(entry));
ufd__delete(&entry->waited_threads); ufd__delete(&entry->waited_threads);
// Exit from waiting state
UNSET_STATUS(running, WAITING);
} }
// Save returned value if needed // Save returned value if needed
@ -225,6 +222,9 @@ int thread_join(thread_t thread, void** retval)
if (retval) if (retval)
*retval = entry->retvalue; *retval = entry->retvalue;
// Exit from waiting state
UNSET_STATUS(running, WAITING);
// Clean up // Clean up
DBG("(entry, was_alloacted) : %p,%d", entry, WAS_ALLOCATED(entry)); DBG("(entry, was_alloacted) : %p,%d", entry, WAS_ALLOCATED(entry));
if (WAS_ALLOCATED(entry)) { if (WAS_ALLOCATED(entry)) {
@ -242,21 +242,23 @@ void thread_exit(void* retval)
TRACE("Exit thread %p", running); TRACE("Exit thread %p", running);
print_entry(running); print_entry(running);
SET_STATUS(running, FINISHED);
if (IS_WAITED(running)) { if (IS_WAITED(running)) {
// If the thread was waited by another thread, we need to wake it up. // If the thread was waited by another thread, we need to wake it up.
struct context_entry_t* waited = running->retvalue; struct context_entry_t* waiting = running->retvalue;
UNSET_STATUS(running, WAITED);
#ifdef FIBO_STRAT #ifdef FIBO_STRAT
TAILQ_INSERT_HEAD(&scheduler_fifo, waited, link); TAILQ_INSERT_HEAD(&scheduler_fifo, waiting, link);
#else #else
TAILQ_INSERT_TAIL(&scheduler_fifo, waited, link); TAILQ_INSERT_TAIL(&scheduler_fifo, waiting, link);
#endif #endif
} }
running->retvalue = retval; running->retvalue = retval;
if (!TAILQ_EMPTY(&scheduler_fifo)) { SET_STATUS(running, FINISHED);
while (!TAILQ_EMPTY(&scheduler_fifo))
thread_yield(); thread_yield();
}
exit(0); exit(0);
} }
@ -264,25 +266,30 @@ void clear_context(void)
{ {
TRACE("INSIDE CLEAR"); TRACE("INSIDE CLEAR");
struct context_entry_t* last = NULL; struct context_entry_t* last = NULL;
// Loop over remaining threads to clean them from the heap. // Loop over remaining threads to clean them from the heap.
while (!TAILQ_EMPTY(&scheduler_fifo)) { while (!TAILQ_EMPTY(&scheduler_fifo)) {
last = TAILQ_FIRST(&scheduler_fifo); last = TAILQ_FIRST(&scheduler_fifo);
TAILQ_REMOVE(&scheduler_fifo, last, link); TAILQ_REMOVE(&scheduler_fifo, last, link);
if (WAS_ALLOCATED(last)) {
if (WAS_ALLOCATED(last))
VALGRIND_STACK_DEREGISTER(last->valgrind_id); VALGRIND_STACK_DEREGISTER(last->valgrind_id);
}
if (IS_WAITED(last)) { if (IS_WAITED(last)) {
struct context_entry_t* waited = last->retvalue; struct context_entry_t* waiting = last->retvalue;
TAILQ_INSERT_TAIL(&scheduler_fifo, waited, link); TAILQ_INSERT_TAIL(&scheduler_fifo, waiting, link);
} }
free(last); free(last);
} }
while (!TAILQ_EMPTY(&context_to_freed)) { while (!TAILQ_EMPTY(&context_to_freed)) {
last = TAILQ_FIRST(&context_to_freed); last = TAILQ_FIRST(&context_to_freed);
TAILQ_REMOVE(&context_to_freed, last, link); TAILQ_REMOVE(&context_to_freed, last, link);
if (WAS_ALLOCATED(last)) {
if (WAS_ALLOCATED(last))
VALGRIND_STACK_DEREGISTER(last->valgrind_id); VALGRIND_STACK_DEREGISTER(last->valgrind_id);
}
free(last); free(last);
} }

View File

@ -57,5 +57,6 @@ void ufd__delete(struct ufd_t* th)
struct ufd_t* child; struct ufd_t* child;
TAILQ_FOREACH(child, &th->children, link) { TAILQ_FOREACH(child, &th->children, link) {
child->parent = NULL; child->parent = NULL;
child->repr = child;
} }
} }