/trunk/kernel/generic/include/proc/task.h |
---|
82,6 → 82,8 |
*/ |
mutex_t futexes_lock; |
btree_t futexes; /**< B+tree of futexes referenced by this task. */ |
uint64_t cycles; /**< Accumulated accounting. */ |
}; |
extern spinlock_t tasks_lock; |
93,6 → 95,7 |
extern task_t *task_run_program(void *program_addr, char *name); |
extern task_t *task_find_by_id(task_id_t id); |
extern int task_kill(task_id_t id); |
extern uint64_t task_get_accounting(task_t *t); |
#ifndef task_create_arch |
/trunk/kernel/generic/src/main/kinit.c |
---|
161,7 → 161,7 |
continue; |
} |
task_t *utask = task_run_program((void *) init.tasks[i].addr, "USPACE"); |
task_t *utask = task_run_program((void *) init.tasks[i].addr, "uspace"); |
if (utask) { |
/* |
* Set capabilities to init userspace tasks. |
/trunk/kernel/generic/src/main/main.c |
---|
259,7 → 259,7 |
/* |
* Create kernel task. |
*/ |
k = task_create(AS_KERNEL, "KERNEL"); |
k = task_create(AS_KERNEL, "kernel"); |
if (!k) |
panic("can't create kernel task\n"); |
/trunk/kernel/generic/src/console/cmd.c |
---|
56,6 → 56,7 |
#include <cpu.h> |
#include <mm/tlb.h> |
#include <arch/mm/tlb.h> |
#include <mm/as.h> |
#include <mm/frame.h> |
#include <main/version.h> |
#include <mm/slab.h> |
858,17 → 859,16 |
return 1; |
} |
static bool run_test(const test_t * test) |
static void test_wrapper(void *arg) |
{ |
printf("%s\t\t%s\n", test->name, test->desc); |
test_t *test = (test_t *) arg; |
/* Update and read thread accounting |
for benchmarking */ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&THREAD->lock); |
thread_update_accounting(); |
uint64_t t0 = THREAD->cycles; |
spinlock_unlock(&THREAD->lock); |
spinlock_lock(&TASK->lock); |
uint64_t t0 = task_get_accounting(TASK); |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
/* Execute the test */ |
876,10 → 876,9 |
/* Update and read thread accounting */ |
ipl = interrupts_disable(); |
spinlock_lock(&THREAD->lock); |
thread_update_accounting(); |
uint64_t dt = THREAD->cycles - t0; |
spinlock_unlock(&THREAD->lock); |
spinlock_lock(&TASK->lock); |
uint64_t dt = task_get_accounting(TASK) - t0; |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
printf("Time: %llu cycles\n", dt); |
886,13 → 885,41 |
if (ret == NULL) { |
printf("Test passed\n"); |
return true; |
// return true; |
return; |
} |
printf("%s\n", ret); |
return false; |
// return false; |
} |
static bool run_test(const test_t *test) |
{ |
printf("%s\t\t%s\n", test->name, test->desc); |
/* Create separate task and thread |
for the test */ |
task_t *ta = task_create(AS_KERNEL, "test"); |
if (ta == NULL) { |
printf("Unable to create test task\n"); |
return false; |
} |
thread_t *t = thread_create(test_wrapper, (void *) test, ta, 0, "test_main"); |
if (t == NULL) { |
printf("Unable to create test main thread\n"); |
task_destroy(ta); |
return false; |
} |
/* Run the test */ |
thread_ready(t); |
thread_join(t); |
thread_detach(t); |
return true; |
} |
/** Command for returning kernel tests |
* |
* @param argv Argument vector. |
/trunk/kernel/generic/src/proc/task.c |
---|
119,6 → 119,7 |
ta->capabilities = 0; |
ta->accept_new_threads = true; |
ta->cycles = 0; |
ipc_answerbox_init(&ta->answerbox); |
for (i = 0; i < IPC_MAX_PHONES; i++) |
266,6 → 267,36 |
return (task_t *) btree_search(&tasks_btree, (btree_key_t) id, &leaf); |
} |
/** Get accounting data of given task. |
* |
* Note that task_lock on @t must be already held and |
* interrupts must be already disabled. |
* |
* @param t Pointer to thread. |
* |
*/ |
uint64_t task_get_accounting(task_t *t) |
{ |
/* Accumulated value of task */ |
uint64_t ret = t->cycles; |
/* Current values of threads */ |
link_t *cur; |
for (cur = t->th_head.next; cur != &t->th_head; cur = cur->next) { |
thread_t *thr = list_get_instance(cur, thread_t, th_link); |
spinlock_lock(&thr->lock); |
if (thr == THREAD) /* Update accounting of current thread */ |
thread_update_accounting(); |
ret += thr->cycles; |
spinlock_unlock(&thr->lock); |
} |
return ret; |
} |
/** Kill task. |
* |
* @param id ID of the task to be killed. |
344,8 → 375,8 |
ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
printf("taskid name ctx address as active calls callee\n"); |
printf("------ ---------- --- ---------- ---------- ------------ ------>\n"); |
printf("taskid name ctx address as cycles threads calls callee\n"); |
printf("------ ---------- --- ---------- ---------- ---------- ------- ------ ------>\n"); |
for (cur = tasks_btree.leaf_head.next; cur != &tasks_btree.leaf_head; cur = cur->next) { |
btree_node_t *node; |
359,12 → 390,29 |
t = (task_t *) node->value[i]; |
spinlock_lock(&t->lock); |
printf("%-6lld %-10s %-3ld %#10zx %#10zx %12zd", t->taskid, t->name, t->context, t, t->as, atomic_get(&t->active_calls)); |
uint64_t cycles = task_get_accounting(t); |
char suffix; |
if (cycles > 1000000000000000000LL) { |
cycles = cycles / 1000000000000000000LL; |
suffix = 'E'; |
} else if (cycles > 1000000000000LL) { |
cycles = cycles / 1000000000000LL; |
suffix = 'T'; |
} else if (cycles > 1000000LL) { |
cycles = cycles / 1000000LL; |
suffix = 'M'; |
} else |
suffix = ' '; |
printf("%-6lld %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd", t->taskid, t->name, t->context, t, t->as, cycles, suffix, t->refcount, atomic_get(&t->active_calls)); |
for (j = 0; j < IPC_MAX_PHONES; j++) { |
if (t->phones[j].callee) |
printf(" %zd:%#zx", j, t->phones[j].callee); |
} |
printf("\n"); |
spinlock_unlock(&t->lock); |
} |
} |
/trunk/kernel/generic/src/proc/thread.c |
---|
113,11 → 113,27 |
void *arg = THREAD->thread_arg; |
THREAD->last_cycle = get_cycle(); |
/* this is where each thread wakes up after its creation */ |
/* This is where each thread wakes up after its creation */ |
spinlock_unlock(&THREAD->lock); |
interrupts_enable(); |
f(arg); |
/* Accumulate accounting to the task */ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&THREAD->lock); |
thread_update_accounting(); |
uint64_t cycles = THREAD->cycles; |
THREAD->cycles = 0; |
spinlock_unlock(&THREAD->lock); |
spinlock_lock(&TASK->lock); |
TASK->cycles += cycles; |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
thread_exit(); |
/* not reached */ |
} |
533,7 → 549,7 |
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
printf("tid name address state task ctx code stack cycles cpu kst wq\n"); |
printf("tid name address state task ctx code stack cycles cpu kstack waitqueue\n"); |
printf("------ ---------- ---------- -------- ---------- --- ---------- ---------- ---------- ---- ---------- ----------\n"); |
for (cur = threads_btree.leaf_head.next; cur != &threads_btree.leaf_head; cur = cur->next) { |
603,8 → 619,6 |
* Note that thread_lock on THREAD must be already held and |
* interrupts must be already disabled. |
* |
* @param t Pointer to thread. |
* |
*/ |
void thread_update_accounting(void) |
{ |