Ignore:
File:
1 edited

Legend:

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

    r121966e r8658f89  
    7575static task_id_t task_counter = 0;
    7676
    77 /* Forward declarations. */
    78 static void task_kill_internal(task_t *);
    79 
    8077/** Initialize kernel tasks support. */
    8178void task_init(void)
     
    8683
    8784/*
    88  * The idea behind this walker is to kill and count all tasks different from
     85 * The idea behind this walker is to remember a single task different from
    8986 * TASK.
    9087 */
     
    9289{
    9390        task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    94         unsigned *cnt = (unsigned *) arg;
    95 
    96         if (t != TASK) {
    97                 (*cnt)++;
    98 #ifdef CONFIG_DEBUG
    99                 printf("[%"PRIu64"] ", t->taskid);
    100 #endif
    101                 task_kill_internal(t);
     91        task_t **tp = (task_t **) arg;
     92
     93        if (t != TASK) {
     94                *tp = t;
     95                return false;   /* stop walking */
    10296        }
    10397
     
    108102void task_done(void)
    109103{
    110         unsigned tasks_left;
    111 
     104        task_t *t;
    112105        do { /* Repeat until there are any tasks except TASK */
     106               
    113107                /* Messing with task structures, avoid deadlock */
    114 #ifdef CONFIG_DEBUG
    115                 printf("Killing tasks... ");
    116 #endif
    117108                ipl_t ipl = interrupts_disable();
    118109                spinlock_lock(&tasks_lock);
    119                 tasks_left = 0;
    120                 avltree_walk(&tasks_tree, task_done_walker, &tasks_left);
    121                 spinlock_unlock(&tasks_lock);
    122                 interrupts_restore(ipl);
    123                 thread_sleep(1);
     110               
     111                t = NULL;
     112                avltree_walk(&tasks_tree, task_done_walker, &t);
     113               
     114                if (t != NULL) {
     115                        task_id_t id = t->taskid;
     116                       
     117                        spinlock_unlock(&tasks_lock);
     118                        interrupts_restore(ipl);
     119                       
    124120#ifdef CONFIG_DEBUG
    125                 printf("\n");
    126 #endif
    127         } while (tasks_left);
     121                        printf("Killing task %" PRIu64 "\n", id);
     122#endif                 
     123                        task_kill(id);
     124                        thread_usleep(10000);
     125                } else {
     126                        spinlock_unlock(&tasks_lock);
     127                        interrupts_restore(ipl);
     128                }
     129               
     130        } while (t != NULL);
    128131}
    129132
     
    347350}
    348351
    349 static void task_kill_internal(task_t *ta)
    350 {
    351         link_t *cur;
    352 
    353         /*
    354          * Interrupt all threads.
    355          */
    356         spinlock_lock(&ta->lock);
    357         for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
    358                 thread_t *thr;
    359                 bool sleeping = false;
    360                
    361                 thr = list_get_instance(cur, thread_t, th_link);
    362                
    363                 spinlock_lock(&thr->lock);
    364                 thr->interrupted = true;
    365                 if (thr->state == Sleeping)
    366                         sleeping = true;
    367                 spinlock_unlock(&thr->lock);
    368                
    369                 if (sleeping)
    370                         waitq_interrupt_sleep(thr);
    371         }
    372         spinlock_unlock(&ta->lock);
    373 }
    374 
    375352/** Kill task.
    376353 *
     
    386363        ipl_t ipl;
    387364        task_t *ta;
     365        link_t *cur;
    388366
    389367        if (id == 1)
     
    397375                return ENOENT;
    398376        }
    399         task_kill_internal(ta);
    400377        spinlock_unlock(&tasks_lock);
     378       
     379        /*
     380         * Interrupt all threads.
     381         */
     382        spinlock_lock(&ta->lock);
     383        for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
     384                thread_t *thr;
     385                bool sleeping = false;
     386               
     387                thr = list_get_instance(cur, thread_t, th_link);
     388               
     389                spinlock_lock(&thr->lock);
     390                thr->interrupted = true;
     391                if (thr->state == Sleeping)
     392                        sleeping = true;
     393                spinlock_unlock(&thr->lock);
     394               
     395                if (sleeping)
     396                        waitq_interrupt_sleep(thr);
     397        }
     398        spinlock_unlock(&ta->lock);
    401399        interrupts_restore(ipl);
     400       
    402401        return 0;
    403402}
Note: See TracChangeset for help on using the changeset viewer.