diff --git a/src/thread/thread.c b/src/thread/thread.c index cfece21..5363bdd 100644 --- a/src/thread/thread.c +++ b/src/thread/thread.c @@ -215,9 +215,6 @@ int thread_join(thread_t thread, void** retval) } while (!IS_FINISHED(entry)); ufd__delete(&entry->waited_threads); - - // Exit from waiting state - UNSET_STATUS(running, WAITING); } // Save returned value if needed @@ -225,6 +222,9 @@ int thread_join(thread_t thread, void** retval) if (retval) *retval = entry->retvalue; + // Exit from waiting state + UNSET_STATUS(running, WAITING); + // Clean up DBG("(entry, was_alloacted) : %p,%d", entry, WAS_ALLOCATED(entry)); if (WAS_ALLOCATED(entry)) { @@ -242,21 +242,23 @@ void thread_exit(void* retval) TRACE("Exit thread %p", running); print_entry(running); - SET_STATUS(running, FINISHED); if (IS_WAITED(running)) { // 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 - TAILQ_INSERT_HEAD(&scheduler_fifo, waited, link); + TAILQ_INSERT_HEAD(&scheduler_fifo, waiting, link); #else - TAILQ_INSERT_TAIL(&scheduler_fifo, waited, link); + TAILQ_INSERT_TAIL(&scheduler_fifo, waiting, link); #endif } running->retvalue = retval; - if (!TAILQ_EMPTY(&scheduler_fifo)) { + SET_STATUS(running, FINISHED); + while (!TAILQ_EMPTY(&scheduler_fifo)) thread_yield(); - } + exit(0); } @@ -264,25 +266,30 @@ void clear_context(void) { TRACE("INSIDE CLEAR"); struct context_entry_t* last = NULL; + // Loop over remaining threads to clean them from the heap. while (!TAILQ_EMPTY(&scheduler_fifo)) { last = TAILQ_FIRST(&scheduler_fifo); TAILQ_REMOVE(&scheduler_fifo, last, link); - if (WAS_ALLOCATED(last)) { + + if (WAS_ALLOCATED(last)) VALGRIND_STACK_DEREGISTER(last->valgrind_id); - } + if (IS_WAITED(last)) { - struct context_entry_t* waited = last->retvalue; - TAILQ_INSERT_TAIL(&scheduler_fifo, waited, link); + struct context_entry_t* waiting = last->retvalue; + TAILQ_INSERT_TAIL(&scheduler_fifo, waiting, link); } + free(last); } + while (!TAILQ_EMPTY(&context_to_freed)) { last = TAILQ_FIRST(&context_to_freed); TAILQ_REMOVE(&context_to_freed, last, link); - if (WAS_ALLOCATED(last)) { + + if (WAS_ALLOCATED(last)) VALGRIND_STACK_DEREGISTER(last->valgrind_id); - } + free(last); } diff --git a/src/utils/ufd.c b/src/utils/ufd.c index 98e115b..e74a154 100644 --- a/src/utils/ufd.c +++ b/src/utils/ufd.c @@ -57,5 +57,6 @@ void ufd__delete(struct ufd_t* th) struct ufd_t* child; TAILQ_FOREACH(child, &th->children, link) { child->parent = NULL; + child->repr = child; } }