Changeset 48e7dd6 in mainline for generic/src/proc/task.c


Ignore:
Timestamp:
2006-06-08T09:03:29Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
22bea15
Parents:
4bc141c
Message:

Collect Undead threads while waiting to join uinit.
Rename ktaskkill to ktaskgc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • generic/src/proc/task.c

    r4bc141c r48e7dd6  
    7272
    7373static void ktaskclnp(void *arg);
    74 static void ktaskkill(void *arg);
     74static void ktaskgc(void *arg);
    7575
    7676/** Initialize tasks
     
    222222         * Create killer thread for the new task.
    223223         */
    224         t2 = thread_create(ktaskkill, t1, task, 0, "ktaskkill");
     224        t2 = thread_create(ktaskgc, t1, task, 0, "ktaskgc");
    225225        ASSERT(t2);
    226226        thread_ready(t2);
     
    373373        thread_t *t = NULL, *main_thread;
    374374        link_t *cur;
     375        bool again;
    375376
    376377        thread_detach(THREAD);
     
    385386         * Find a thread to join.
    386387         */
     388        again = false;
    387389        for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
    388390                t = list_get_instance(cur, thread_t, th_link);
    389                 if (t == THREAD)
     391
     392                spinlock_lock(&t->lock);
     393                if (t == THREAD) {
     394                        spinlock_unlock(&t->lock);
    390395                        continue;
    391                 else if (t == main_thread)
     396                } else if (t == main_thread) {
     397                        spinlock_unlock(&t->lock);
    392398                        continue;
    393                 else
     399                } else if (t->join_type != None) {
     400                        spinlock_unlock(&t->lock);
     401                        again = true;
     402                        continue;
     403                } else {
     404                        t->join_type = TaskClnp;
     405                        spinlock_unlock(&t->lock);
     406                        again = false;
    394407                        break;
     408                }
    395409        }
    396410       
     
    398412        interrupts_restore(ipl);
    399413       
     414        if (again) {
     415                /*
     416                 * Other cleanup (e.g. ktaskgc) is in progress.
     417                 */
     418                scheduler();
     419                goto loop;
     420        }
     421       
    400422        if (t != THREAD) {
    401                 ASSERT(t != main_thread);       /* uninit is joined and detached in ktaskkill */
     423                ASSERT(t != main_thread);       /* uninit is joined and detached in ktaskgc */
    402424                thread_join(t);
    403425                thread_detach(t);
     
    418440 *
    419441 * This thread waits until the main userspace thread (i.e. uninit) exits.
    420  * When this happens, the task is killed.
     442 * When this happens, the task is killed. In the meantime, exited threads
     443 * are garbage collected.
    421444 *
    422445 * @param arg Pointer to the thread structure of the task's main thread.
    423446 */
    424 void ktaskkill(void *arg)
     447void ktaskgc(void *arg)
    425448{
    426449        thread_t *t = (thread_t *) arg;
    427        
     450loop:   
    428451        /*
    429452         * Userspace threads cannot detach themselves,
    430453         * therefore the thread pointer is guaranteed to be valid.
    431454         */
    432         thread_join(t); /* sleep uninterruptibly here! */
     455        if (thread_join_timeout(t, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {      /* sleep uninterruptibly here! */
     456                ipl_t ipl;
     457                link_t *cur;
     458                thread_t *thr = NULL;
     459       
     460                /*
     461                 * The join timed out. Try to do some garbage collection of Undead threads.
     462                 */
     463more_gc:               
     464                ipl = interrupts_disable();
     465                spinlock_lock(&TASK->lock);
     466               
     467                for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
     468                        thr = list_get_instance(cur, thread_t, th_link);
     469                        spinlock_lock(&thr->lock);
     470                        if (thr->state == Undead && thr->join_type == None) {
     471                                thr->join_type = TaskGC;
     472                                spinlock_unlock(&thr->lock);
     473                                break;
     474                        }
     475                        spinlock_unlock(&thr->lock);
     476                        thr = NULL;
     477                }
     478                spinlock_unlock(&TASK->lock);
     479               
     480                if (thr) {
     481                        thread_join(thr);
     482                        thread_detach(thr);
     483                        scheduler();
     484                        goto more_gc;
     485                }
     486                       
     487                goto loop;
     488        }
    433489        thread_detach(t);
    434490        task_kill(TASK->taskid);
Note: See TracChangeset for help on using the changeset viewer.