//Free memory for the argument thread. int minithread_free(minithread_t thread) { if ( thread->sb ) { minithread_free_stack(thread->sb); } free(thread); return 0; }
int clean_up(){ minithread_t dead = NULL; while (1){ semaphore_P(dead_sem); semaphore_P(dead_q_lock); if (queue_dequeue(dead_q, (void**)(&dead)) == -1){ semaphore_V(dead_q_lock); return -1; } else { semaphore_V(dead_q_lock); minithread_free_stack(dead->stackbase); free(dead); } } return -1; }
int minithread_cleanup(arg_t arg) { // Create a TCB to store the TCBs from the cleanup queue minithread_t tcb; // DO NOT MALLOC ANYTHING (memory leak fix) // ISO C90 interrupt_level_t prev_level; while (1) { // We're going to check & edit the cleanup queue, so disable interrupts prev_level = set_interrupt_level(DISABLED); // Wait to be woken up - must be inside interrupt disabled, as used there before semaphore_P(cleanup_sem); // While there are threads that need to be cleaned while (queue_length(cleanup_queue) > 0) { // Get the next TCB for the thread to free up queue_dequeue(cleanup_queue, (void**) &tcb); // Free the stack minithread_free_stack(*(tcb->stack_base)); // Free the TCB & its malloc'd members free(tcb->stack_base); free(tcb->stack_top); free(tcb); } // Restore the old interrupt level set_interrupt_level(prev_level); } return 0; }
static void minithread_free(minithread_t *t) { assert(t); minithread_free_stack(t->base); free(t); t = NULL; }