Ignore:
File:
1 edited

Legend:

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

    r22e6802 r7ed8530  
    11/*
    2  * Copyright (c) 2001-2004 Jakub Jermar
     2 * Copyright (c) 2010 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    5050#include <synch/rwlock.h>
    5151#include <cpu.h>
    52 #include <func.h>
     52#include <str.h>
    5353#include <context.h>
    5454#include <adt/avl.h>
     
    7676
    7777/** Thread states */
    78 char *thread_states[] = {
     78const char *thread_states[] = {
    7979        "Invalid",
    8080        "Running",
     
    8484        "Exiting",
    8585        "Lingering"
    86 };
     86};
     87
     88typedef struct {
     89        thread_id_t thread_id;
     90        thread_t *thread;
     91} thread_iterator_t;
    8792
    8893/** Lock protecting the threads_tree AVL tree.
     
    132137        spinlock_lock(&THREAD->lock);
    133138        if (!THREAD->uncounted) {
    134                 thread_update_accounting();
    135                 uint64_t cycles = THREAD->cycles;
    136                 THREAD->cycles = 0;
     139                thread_update_accounting(true);
     140                uint64_t ucycles = THREAD->ucycles;
     141                THREAD->ucycles = 0;
     142                uint64_t kcycles = THREAD->kcycles;
     143                THREAD->kcycles = 0;
     144
    137145                spinlock_unlock(&THREAD->lock);
    138146               
    139147                spinlock_lock(&TASK->lock);
    140                 TASK->cycles += cycles;
     148                TASK->ucycles += ucycles;
     149                TASK->kcycles += kcycles;
    141150                spinlock_unlock(&TASK->lock);
    142151        } else
     
    264273
    265274        atomic_inc(&nrdy);
     275        // FIXME: Why is the avg value never read?
    266276        avg = atomic_get(&nrdy) / config.cpu_active;
    267277        atomic_inc(&cpu->nrdy);
     
    288298 */
    289299thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
    290     int flags, char *name, bool uncounted)
     300    int flags, const char *name, bool uncounted)
    291301{
    292302        thread_t *t;
     
    322332        t->thread_arg = arg;
    323333        t->ticks = -1;
    324         t->cycles = 0;
     334        t->ucycles = 0;
     335        t->kcycles = 0;
    325336        t->uncounted = uncounted;
    326337        t->priority = -1;               /* start in rq[0] */
     
    398409
    399410        /*
    400          * t is guaranteed to be the very last thread of its task.
    401          * It is safe to destroy the task.
     411         * Drop the reference to the containing task.
    402412         */
    403         if (atomic_predec(&t->task->refcount) == 0)
    404                 task_destroy(t->task);
     413        task_release(t->task);
    405414       
    406415        slab_free(thread_slab, t);
     
    425434        spinlock_lock(&task->lock);
    426435
    427         atomic_inc(&task->refcount);
     436        /* Hold a reference to the task. */
     437        task_hold(task);
    428438
    429439        /* Must not count kbox thread into lifecount */
     
    613623        thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node);
    614624       
    615         uint64_t cycles;
    616         char suffix;
    617         order(t->cycles, &cycles, &suffix);
     625        uint64_t ucycles, kcycles;
     626        char usuffix, ksuffix;
     627        order_suffix(t->ucycles, &ucycles, &usuffix);
     628        order_suffix(t->kcycles, &kcycles, &ksuffix);
    618629
    619630#ifdef __32_BITS__
    620         printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ",
    621             t->tid, t->name, t, thread_states[t->state], t->task,
    622         t->task->context, t->thread_code, t->kstack, cycles, suffix);
     631        printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9"
     632                PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
     633                thread_states[t->state], t->task, t->task->context, t->thread_code,
     634                t->kstack, ucycles, usuffix, kcycles, ksuffix);
    623635#endif
    624636
    625637#ifdef __64_BITS__
    626         printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ",
    627             t->tid, t->name, t, thread_states[t->state], t->task,
    628         t->task->context, t->thread_code, t->kstack, cycles, suffix);
     638        printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9"
     639                PRIu64 "%c %9" PRIu64 "%c ", t->tid, t->name, t,
     640                thread_states[t->state], t->task, t->task->context, t->thread_code,
     641                t->kstack, ucycles, usuffix, kcycles, ksuffix);
    629642#endif
    630643                       
     
    660673#ifdef __32_BITS__     
    661674        printf("tid    name       address    state    task       "
    662                 "ctx code       stack      cycles     cpu  "
     675                "ctx code       stack      ucycles    kcycles    cpu  "
    663676                "waitqueue\n");
    664677        printf("------ ---------- ---------- -------- ---------- "
    665                 "--- ---------- ---------- ---------- ---- "
     678                "--- ---------- ---------- ---------- ---------- ---- "
    666679                "----------\n");
    667680#endif
     
    669682#ifdef __64_BITS__
    670683        printf("tid    name       address            state    task               "
    671                 "ctx code               stack              cycles     cpu  "
     684                "ctx code               stack              ucycles    kcycles    cpu  "
    672685                "waitqueue\n");
    673686        printf("------ ---------- ------------------ -------- ------------------ "
    674                 "--- ------------------ ------------------ ---------- ---- "
     687                "--- ------------------ ------------------ ---------- ---------- ---- "
    675688                "------------------\n");
    676689#endif
     
    705718 * interrupts must be already disabled.
    706719 *
    707  */
    708 void thread_update_accounting(void)
     720 * @param user  True to update user accounting, false for kernel.
     721 */
     722void thread_update_accounting(bool user)
    709723{
    710724        uint64_t time = get_cycle();
    711         THREAD->cycles += time - THREAD->last_cycle;
     725        if (user) {
     726                THREAD->ucycles += time - THREAD->last_cycle;
     727        } else {
     728                THREAD->kcycles += time - THREAD->last_cycle;
     729        }
    712730        THREAD->last_cycle = time;
    713731}
     732
     733static bool thread_search_walker(avltree_node_t *node, void *arg)
     734{
     735        thread_t *thread =
     736            (thread_t *) avltree_get_instance(node, thread_t, threads_tree_node);
     737        thread_iterator_t *iterator = (thread_iterator_t *) arg;
     738       
     739        if (thread->tid == iterator->thread_id) {
     740                iterator->thread = thread;
     741                return false;
     742        }
     743       
     744        return true;
     745}
     746
     747/** Find thread structure corresponding to thread ID.
     748 *
     749 * The threads_lock must be already held by the caller of this function and
     750 * interrupts must be disabled.
     751 *
     752 * @param id Thread ID.
     753 *
     754 * @return Thread structure address or NULL if there is no such thread ID.
     755 *
     756 */
     757thread_t *thread_find_by_id(thread_id_t thread_id)
     758{
     759        thread_iterator_t iterator;
     760       
     761        iterator.thread_id = thread_id;
     762        iterator.thread = NULL;
     763       
     764        avltree_walk(&threads_tree, thread_search_walker, (void *) &iterator);
     765       
     766        return iterator.thread;
     767}
     768
    714769
    715770/** Process syscall to create new thread.
Note: See TracChangeset for help on using the changeset viewer.