Changeset b50b5af2 in mainline for kernel/generic/src/proc/task.c


Ignore:
Timestamp:
2009-08-22T10:48:00Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
04803bf
Parents:
1ea99cc (diff), a71c158 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r1ea99cc rb50b5af2  
    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
     
    200197        interrupts_restore(ipl);
    201198       
    202         /*
    203          * Notify about task creation.
    204          */
    205         if (event_is_subscribed(EVENT_WAIT))
    206                 event_notify_3(EVENT_WAIT, TASK_CREATE, LOWER32(ta->taskid),
    207                     UPPER32(ta->taskid));
    208        
    209199        return ta;
    210200}
     
    238228        if (atomic_predec(&t->as->refcount) == 0)
    239229                as_destroy(t->as);
    240        
    241         /*
    242          * Notify about task destruction.
    243          */
    244         if (event_is_subscribed(EVENT_WAIT))
    245                 event_notify_3(EVENT_WAIT, TASK_DESTROY, LOWER32(t->taskid),
    246                     UPPER32(t->taskid));
    247230       
    248231        free(t);
     
    350333}
    351334
    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;
     335static void task_kill_internal(task_t *ta)
     336{
    365337        link_t *cur;
    366338
    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        
    379339        /*
    380340         * Interrupt all threads.
     
    397357        }
    398358        spinlock_unlock(&ta->lock);
     359}
     360
     361/** Kill task.
     362 *
     363 * This function is idempotent.
     364 * It signals all the task's threads to bail it out.
     365 *
     366 * @param id            ID of the task to be killed.
     367 *
     368 * @return              Zero on success or an error code from errno.h.
     369 */
     370int task_kill(task_id_t id)
     371{
     372        ipl_t ipl;
     373        task_t *ta;
     374
     375        if (id == 1)
     376                return EPERM;
     377       
     378        ipl = interrupts_disable();
     379        spinlock_lock(&tasks_lock);
     380        if (!(ta = task_find_by_id(id))) {
     381                spinlock_unlock(&tasks_lock);
     382                interrupts_restore(ipl);
     383                return ENOENT;
     384        }
     385        task_kill_internal(ta);
     386        spinlock_unlock(&tasks_lock);
    399387        interrupts_restore(ipl);
    400        
    401388        return 0;
    402389}
Note: See TracChangeset for help on using the changeset viewer.