Ignore:
File:
1 edited

Legend:

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

    r8658f89 r121966e  
    7575static task_id_t task_counter = 0;
    7676
     77/* Forward declarations. */
     78static void task_kill_internal(task_t *);
     79
    7780/** Initialize kernel tasks support. */
    7881void task_init(void)
     
    8386
    8487/*
    85  * The idea behind this walker is to remember a single task different from
     88 * The idea behind this walker is to kill and count all tasks different from
    8689 * TASK.
    8790 */
     
    8992{
    9093        task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    91         task_t **tp = (task_t **) arg;
    92 
    93         if (t != TASK) {
    94                 *tp = t;
    95                 return false;   /* stop walking */
     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);
    96102        }
    97103
     
    102108void task_done(void)
    103109{
    104         task_t *t;
     110        unsigned tasks_left;
     111
    105112        do { /* Repeat until there are any tasks except TASK */
    106                
    107113                /* Messing with task structures, avoid deadlock */
     114#ifdef CONFIG_DEBUG
     115                printf("Killing tasks... ");
     116#endif
    108117                ipl_t ipl = interrupts_disable();
    109118                spinlock_lock(&tasks_lock);
    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                        
     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);
    120124#ifdef CONFIG_DEBUG
    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);
     125                printf("\n");
     126#endif
     127        } while (tasks_left);
    131128}
    132129
     
    350347}
    351348
    352 /** Kill task.
    353  *
    354  * This function is idempotent.
    355  * It signals all the task's threads to bail it out.
    356  *
    357  * @param id            ID of the task to be killed.
    358  *
    359  * @return              Zero on success or an error code from errno.h.
    360  */
    361 int task_kill(task_id_t id)
    362 {
    363         ipl_t ipl;
    364         task_t *ta;
     349static void task_kill_internal(task_t *ta)
     350{
    365351        link_t *cur;
    366352
    367         if (id == 1)
    368                 return EPERM;
    369        
    370         ipl = interrupts_disable();
    371         spinlock_lock(&tasks_lock);
    372         if (!(ta = task_find_by_id(id))) {
    373                 spinlock_unlock(&tasks_lock);
    374                 interrupts_restore(ipl);
    375                 return ENOENT;
    376         }
    377         spinlock_unlock(&tasks_lock);
    378        
    379353        /*
    380354         * Interrupt all threads.
     
    397371        }
    398372        spinlock_unlock(&ta->lock);
     373}
     374
     375/** Kill task.
     376 *
     377 * This function is idempotent.
     378 * It signals all the task's threads to bail it out.
     379 *
     380 * @param id            ID of the task to be killed.
     381 *
     382 * @return              Zero on success or an error code from errno.h.
     383 */
     384int task_kill(task_id_t id)
     385{
     386        ipl_t ipl;
     387        task_t *ta;
     388
     389        if (id == 1)
     390                return EPERM;
     391       
     392        ipl = interrupts_disable();
     393        spinlock_lock(&tasks_lock);
     394        if (!(ta = task_find_by_id(id))) {
     395                spinlock_unlock(&tasks_lock);
     396                interrupts_restore(ipl);
     397                return ENOENT;
     398        }
     399        task_kill_internal(ta);
     400        spinlock_unlock(&tasks_lock);
    399401        interrupts_restore(ipl);
    400        
    401402        return 0;
    402403}
Note: See TracChangeset for help on using the changeset viewer.