Ignore:
File:
1 edited

Legend:

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

    rd3808d3 r41df2827  
    11/*
    2  * Copyright (c) 2010 Jakub Jermar
     2 * Copyright (c) 2001-2004 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    3333/**
    3434 * @file
    35  * @brief Task management.
     35 * @brief       Task management.
    3636 */
    3737
     
    5353#include <errno.h>
    5454#include <func.h>
    55 #include <str.h>
     55#include <string.h>
    5656#include <memstr.h>
    5757#include <syscall/copy.h>
     
    6666 * The task is guaranteed to exist after it was found in the tasks_tree as
    6767 * long as:
    68  *
    6968 * @li the tasks_lock is held,
    7069 * @li the task's lock is held when task's lock is acquired before releasing
     
    10099        task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    101100        unsigned *cnt = (unsigned *) arg;
    102        
     101
    103102        if (t != TASK) {
    104103                (*cnt)++;
     
    108107                task_kill_internal(t);
    109108        }
    110        
    111         /* Continue the walk */
    112         return true;
     109
     110        return true;    /* continue the walk */
    113111}
    114112
     
    117115{
    118116        unsigned tasks_left;
    119        
     117
    120118        do { /* Repeat until there are any tasks except TASK */
    121119                /* Messing with task structures, avoid deadlock */
     
    140138        task_t *ta = obj;
    141139        int i;
    142        
     140
    143141        atomic_set(&ta->refcount, 0);
    144142        atomic_set(&ta->lifecount, 0);
    145143        atomic_set(&ta->active_calls, 0);
    146        
     144
    147145        spinlock_initialize(&ta->lock, "task_ta_lock");
    148146        mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE);
    149        
     147
    150148        list_initialize(&ta->th_head);
    151149        list_initialize(&ta->sync_box_head);
    152        
     150
    153151        ipc_answerbox_init(&ta->answerbox, ta);
    154152        for (i = 0; i < IPC_MAX_PHONES; i++)
    155153                ipc_phone_init(&ta->phones[i]);
    156        
     154
    157155#ifdef CONFIG_UDEBUG
    158156        /* Init kbox stuff */
     
    161159        mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
    162160#endif
    163        
     161
    164162        return 0;
    165163}
     
    167165/** Create new task with no threads.
    168166 *
    169  * @param as   Task's address space.
    170  * @param name Symbolic name (a copy is made).
    171  *
    172  * @return New task's structure.
    173  *
    174  */
    175 task_t *task_create(as_t *as, const char *name)
     167 * @param as            Task's address space.
     168 * @param name          Symbolic name (a copy is made).
     169 *
     170 * @return              New task's structure.
     171 *
     172 */
     173task_t *task_create(as_t *as, char *name)
    176174{
    177175        ipl_t ipl;
     
    183181        memcpy(ta->name, name, TASK_NAME_BUFLEN);
    184182        ta->name[TASK_NAME_BUFLEN - 1] = 0;
    185        
     183
    186184        ta->context = CONTEXT;
    187185        ta->capabilities = 0;
    188         ta->ucycles = 0;
    189         ta->kcycles = 0;
    190 
    191         ta->ipc_info.call_sent = 0;
    192         ta->ipc_info.call_recieved = 0;
    193         ta->ipc_info.answer_sent = 0;
    194         ta->ipc_info.answer_recieved = 0;
    195         ta->ipc_info.irq_notif_recieved = 0;
    196         ta->ipc_info.forwarded = 0;
     186        ta->cycles = 0;
    197187
    198188#ifdef CONFIG_UDEBUG
    199189        /* Init debugging stuff */
    200190        udebug_task_init(&ta->udebug);
    201        
     191
    202192        /* Init kbox stuff */
    203193        ta->kb.finished = false;
    204194#endif
    205        
     195
    206196        if ((ipc_phone_0) &&
    207197            (context_check(ipc_phone_0->task->context, ta->context)))
    208198                ipc_phone_connect(&ta->phones[0], ipc_phone_0);
    209        
     199
    210200        btree_create(&ta->futexes);
    211201       
    212         /*
    213          * Get a reference to the address space.
    214          */
    215         as_hold(ta->as);
    216 
    217202        ipl = interrupts_disable();
     203        atomic_inc(&as->refcount);
    218204        spinlock_lock(&tasks_lock);
    219205        ta->taskid = ++task_counter;
     
    229215/** Destroy task.
    230216 *
    231  * @param t Task to be destroyed.
    232  *
     217 * @param t             Task to be destroyed.
    233218 */
    234219void task_destroy(task_t *t)
     
    240225        avltree_delete(&tasks_tree, &t->tasks_tree_node);
    241226        spinlock_unlock(&tasks_lock);
    242        
     227
    243228        /*
    244229         * Perform architecture specific task destruction.
    245230         */
    246231        task_destroy_arch(t);
    247        
     232
    248233        /*
    249234         * Free up dynamically allocated state.
    250235         */
    251236        btree_destroy(&t->futexes);
    252        
     237
    253238        /*
    254239         * Drop our reference to the address space.
    255240         */
    256         as_release(t->as);
     241        if (atomic_predec(&t->as->refcount) == 0)
     242                as_destroy(t->as);
    257243       
    258244        slab_free(task_slab, t);
    259 }
    260 
    261 /** Hold a reference to a task.
    262  *
    263  * Holding a reference to a task prevents destruction of that task.
    264  *
    265  * @param t             Task to be held.
    266  */
    267 void task_hold(task_t *t)
    268 {
    269         atomic_inc(&t->refcount);
    270 }
    271 
    272 /** Release a reference to a task.
    273  *
    274  * The last one to release a reference to a task destroys the task.
    275  *
    276  * @param t             Task to be released.
    277  */
    278 void task_release(task_t *t)
    279 {
    280         if ((atomic_predec(&t->refcount)) == 0)
    281                 task_destroy(t);
     245        TASK = NULL;
    282246}
    283247
    284248/** Syscall for reading task ID from userspace.
    285249 *
    286  * @param uspace_task_id Userspace address of 8-byte buffer
    287  *                       where to store current task ID.
    288  *
    289  * @return Zero on success or an error code from @ref errno.h.
    290  *
     250 * @param               uspace_task_id userspace address of 8-byte buffer
     251 *                      where to store current task ID.
     252 *
     253 * @return              Zero on success or an error code from @ref errno.h.
    291254 */
    292255unative_t sys_task_get_id(task_id_t *uspace_task_id)
     
    304267 * The name simplifies identifying the task in the task list.
    305268 *
    306  * @param name The new name for the task. (typically the same
    307  *             as the command used to execute it).
     269 * @param name  The new name for the task. (typically the same
     270 *              as the command used to execute it).
    308271 *
    309272 * @return 0 on success or an error code from @ref errno.h.
    310  *
    311273 */
    312274unative_t sys_task_set_name(const char *uspace_name, size_t name_len)
     
    314276        int rc;
    315277        char namebuf[TASK_NAME_BUFLEN];
    316        
     278
    317279        /* Cap length of name and copy it from userspace. */
    318        
     280
    319281        if (name_len > TASK_NAME_BUFLEN - 1)
    320282                name_len = TASK_NAME_BUFLEN - 1;
    321        
     283
    322284        rc = copy_from_uspace(namebuf, uspace_name, name_len);
    323285        if (rc != 0)
    324286                return (unative_t) rc;
    325        
     287
    326288        namebuf[name_len] = '\0';
    327289        str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
    328        
     290
    329291        return EOK;
    330292}
     
    335297 * interrupts must be disabled.
    336298 *
    337  * @param id Task ID.
    338  *
    339  * @return Task structure address or NULL if there is no such task ID.
    340  *
    341  */
    342 task_t *task_find_by_id(task_id_t id)
    343 {
    344         avltree_node_t *node =
    345             avltree_search(&tasks_tree, (avltree_key_t) id);
    346        
     299 * @param id            Task ID.
     300 *
     301 * @return              Task structure address or NULL if there is no such task
     302 *                      ID.
     303 */
     304task_t *task_find_by_id(task_id_t id) { avltree_node_t *node;
     305       
     306        node = avltree_search(&tasks_tree, (avltree_key_t) id);
     307
    347308        if (node)
    348309                return avltree_get_instance(node, task_t, tasks_tree_node);
    349        
    350310        return NULL;
    351311}
     
    356316 * already disabled.
    357317 *
    358  * @param t       Pointer to thread.
    359  * @param ucycles Out pointer to sum of all user cycles.
    360  * @param kcycles Out pointer to sum of all kernel cycles.
    361  *
    362  */
    363 void task_get_accounting(task_t *t, uint64_t *ucycles, uint64_t *kcycles)
    364 {
    365         /* Accumulated values of task */
    366         uint64_t uret = t->ucycles;
    367         uint64_t kret = t->kcycles;
     318 * @param t             Pointer to thread.
     319 *
     320 * @return              Number of cycles used by the task and all its threads
     321 *                      so far.
     322 */
     323uint64_t task_get_accounting(task_t *t)
     324{
     325        /* Accumulated value of task */
     326        uint64_t ret = t->cycles;
    368327       
    369328        /* Current values of threads */
     
    377336                        if (thr == THREAD) {
    378337                                /* Update accounting of current thread */
    379                                 thread_update_accounting(false);
     338                                thread_update_accounting();
    380339                        }
    381                         uret += thr->ucycles;
    382                         kret += thr->kcycles;
     340                        ret += thr->cycles;
    383341                }
    384342                spinlock_unlock(&thr->lock);
    385343        }
    386344       
    387         *ucycles = uret;
    388         *kcycles = kret;
     345        return ret;
    389346}
    390347
     
    392349{
    393350        link_t *cur;
    394        
     351
    395352        /*
    396353         * Interrupt all threads.
     
    420377 * It signals all the task's threads to bail it out.
    421378 *
    422  * @param id ID of the task to be killed.
    423  *
    424  * @return Zero on success or an error code from errno.h.
    425  *
     379 * @param id            ID of the task to be killed.
     380 *
     381 * @return              Zero on success or an error code from errno.h.
    426382 */
    427383int task_kill(task_id_t id)
     
    450406        task_t *t = avltree_get_instance(node, task_t, tasks_tree_node);
    451407        int j;
    452        
     408               
    453409        spinlock_lock(&t->lock);
    454        
    455         uint64_t ucycles;
    456         uint64_t kcycles;
    457         char usuffix, ksuffix;
    458         task_get_accounting(t, &ucycles, &kcycles);
    459         order_suffix(ucycles, &ucycles, &usuffix);
    460         order_suffix(kcycles, &kcycles, &ksuffix);
    461        
     410                       
     411        uint64_t cycles;
     412        char suffix;
     413        order(task_get_accounting(t), &cycles, &suffix);
     414
    462415#ifdef __32_BITS__     
    463         printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 "%c %9"
    464                 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
    465                 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
    466                 atomic_get(&t->active_calls));
    467 #endif
    468        
     416        printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64
     417            "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
     418            suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
     419#endif
     420
    469421#ifdef __64_BITS__
    470         printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 "%c %9"
    471                 PRIu64 "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as,
    472                 ucycles, usuffix, kcycles, ksuffix, atomic_get(&t->refcount),
    473                 atomic_get(&t->active_calls));
    474 #endif
    475        
     422        printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64
     423            "%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
     424            suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
     425#endif
     426
    476427        for (j = 0; j < IPC_MAX_PHONES; j++) {
    477428                if (t->phones[j].callee)
     
    479430        }
    480431        printf("\n");
    481        
     432                       
    482433        spinlock_unlock(&t->lock);
    483434        return true;
     
    492443        ipl = interrupts_disable();
    493444        spinlock_lock(&tasks_lock);
    494        
    495 #ifdef __32_BITS__
    496         printf("taskid name         ctx address    as        "
    497             " ucycles    kcycles    threads calls  callee\n");
    498         printf("------ ------------ --- ---------- ----------"
    499             " ---------- ---------- ------- ------ ------>\n");
    500 #endif
    501        
     445
     446#ifdef __32_BITS__     
     447        printf("taskid name         ctx address    as         "
     448            "cycles     threads calls  callee\n");
     449        printf("------ ------------ --- ---------- ---------- "
     450            "---------- ------- ------ ------>\n");
     451#endif
     452
    502453#ifdef __64_BITS__
    503         printf("taskid name         ctx address            as                "
    504             " ucycles    kcycles    threads calls  callee\n");
    505         printf("------ ------------ --- ------------------ ------------------"
    506             " ---------- ---------- ---------- ------- ------ ------>\n");
    507 #endif
    508        
     454        printf("taskid name         ctx address            as                 "
     455            "cycles     threads calls  callee\n");
     456        printf("------ ------------ --- ------------------ ------------------ "
     457            "---------- ------- ------ ------>\n");
     458#endif
     459
    509460        avltree_walk(&tasks_tree, task_print_walker, NULL);
    510        
     461
    511462        spinlock_unlock(&tasks_lock);
    512463        interrupts_restore(ipl);
Note: See TracChangeset for help on using the changeset viewer.