Changeset 48e7dd6 in mainline


Ignore:
Timestamp:
2006-06-08T09:03:29Z (18 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.

Location:
generic
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • generic/include/proc/thread.h

    r4bc141c r48e7dd6  
    4747#define THREAD_STACK_SIZE       STACK_SIZE
    4848
     49/**< Thread states. */
    4950enum state {
    5051        Invalid,        /**< It is an error, if thread is found in this state. */
     
    5859
    5960extern char *thread_states[];
     61
     62/**< Join types. */
     63typedef enum {
     64        None,
     65        TaskClnp,       /**< The thread will be joined by ktaskclnp thread. */
     66        TaskGC          /**< The thread will be joined by ktaskgc thread. */
     67} thread_join_type_t;
    6068
    6169#define X_WIRED         (1<<0)
     
    104112        bool interrupted;                       
    105113       
     114        thread_join_type_t      join_type;      /**< Who joinins the thread. */
    106115        bool detached;                          /**< If true, thread_join_timeout() cannot be used on this thread. */
    107116        waitq_t join_wq;                        /**< Waitq for thread_join_timeout(). */
  • 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);
  • generic/src/proc/thread.c

    r4bc141c r48e7dd6  
    337337
    338338        t->interrupted = false;
     339        t->join_type = None;
    339340        t->detached = false;
    340341        waitq_initialize(&t->join_wq);
Note: See TracChangeset for help on using the changeset viewer.