/trunk/kernel/generic/include/proc/thread.h |
---|
145,6 → 145,9 |
task_t *task; /**< Containing task. */ |
uint64_t ticks; /**< Ticks before preemption. */ |
uint64_t cycles; /**< Task accounting. */ |
uint64_t last_cycle; /**< Last sampled cycle. */ |
int priority; /**< Thread's priority. Implemented as index to CPU->rq */ |
uint32_t tid; /**< Thread ID. */ |
189,6 → 192,7 |
extern void thread_register_call_me(void (* call_me)(void *), void *call_me_with); |
extern void thread_print_list(void); |
extern void thread_destroy(thread_t *t); |
extern void thread_update_accounting(void); |
extern bool thread_exists(thread_t *t); |
/* Fpu context slab cache */ |
/trunk/kernel/generic/src/console/cmd.c |
---|
69,10 → 69,6 |
#include <test.h> |
#endif |
#ifdef CONFIG_BENCH |
#include <arch/cycle.h> |
#endif |
/* Data and methods for 'help' command. */ |
static int cmd_help(cmd_arg_t *argv); |
static cmd_info_t help_info = { |
865,14 → 861,28 |
static bool run_test(const test_t * test) |
{ |
printf("%s\t\t%s\n", test->name, test->desc); |
#ifdef CONFIG_BENCH |
uint64_t t0 = get_cycle(); |
#endif |
/* 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); |
interrupts_restore(ipl); |
/* Execute the test */ |
char * ret = test->entry(); |
#ifdef CONFIG_BENCH |
uint64_t dt = get_cycle() - t0; |
/* 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); |
interrupts_restore(ipl); |
printf("Time: %llu cycles\n", dt); |
#endif |
if (ret == NULL) { |
printf("Test passed\n"); |
/trunk/kernel/generic/src/proc/scheduler.c |
---|
47,6 → 47,7 |
#include <time/delay.h> |
#include <arch/asm.h> |
#include <arch/faddr.h> |
#include <arch/cycle.h> |
#include <atomic.h> |
#include <synch/spinlock.h> |
#include <config.h> |
308,6 → 309,10 |
if (THREAD) { |
spinlock_lock(&THREAD->lock); |
/* Update thread accounting */ |
THREAD->cycles += get_cycle() - THREAD->last_cycle; |
#ifndef CONFIG_FPU_LAZY |
fpu_context_save(THREAD->saved_fpu_context); |
#endif |
315,6 → 320,10 |
/* |
* This is the place where threads leave scheduler(); |
*/ |
/* Save current CPU cycle */ |
THREAD->last_cycle = get_cycle(); |
spinlock_unlock(&THREAD->lock); |
interrupts_restore(THREAD->saved_context.ipl); |
/trunk/kernel/generic/src/proc/thread.c |
---|
42,6 → 42,7 |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/asm.h> |
#include <arch/cycle.h> |
#include <arch.h> |
#include <synch/synch.h> |
#include <synch/spinlock.h> |
325,6 → 326,7 |
t->thread_code = func; |
t->thread_arg = arg; |
t->ticks = -1; |
t->cycles = 0; |
t->priority = -1; /* start in rq[0] */ |
t->cpu = NULL; |
t->flags = flags; |
529,6 → 531,9 |
/* Messing with thread structures, avoid deadlock */ |
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
printf("tid name address state task ctx code stack cycles cpu kst wq\n"); |
printf("------ ---------- ---------- -------- ---------- --- ---------- ---------- ---------- ---- ---------- ----------\n"); |
for (cur = threads_btree.leaf_head.next; cur != &threads_btree.leaf_head; cur = cur->next) { |
btree_node_t *node; |
539,16 → 544,34 |
thread_t *t; |
t = (thread_t *) node->value[i]; |
printf("%s: address=%#zx, tid=%zd, state=%s, task=%#zx, context=%ld, code=%#zx, stack=%#zx, cpu=", |
t->name, t, t->tid, thread_states[t->state], t->task, t->task->context, t->thread_code, t->kstack); |
uint64_t cycles; |
char suffix; |
if (t->cycles > 1000000000000000000LL) { |
cycles = t->cycles / 1000000000000000000LL; |
suffix = 'E'; |
} else if (t->cycles > 1000000000000LL) { |
cycles = t->cycles / 1000000000000LL; |
suffix = 'T'; |
} else if (t->cycles > 1000000LL) { |
cycles = t->cycles / 1000000LL; |
suffix = 'M'; |
} else { |
cycles = t->cycles; |
suffix = ' '; |
} |
printf("%-6zd %-10s %#10zx %-8s %#10zx %-3ld %#10zx %#10zx %9llu%c ", t->tid, t->name, t, thread_states[t->state], t->task, t->task->context, t->thread_code, t->kstack, cycles, suffix); |
if (t->cpu) |
printf("cpu%zd", t->cpu->id); |
printf("%-4zd", t->cpu->id); |
else |
printf("none"); |
if (t->state == Sleeping) { |
printf(", kst=%#zx", t->kstack); |
printf(", wq=%#zx", t->sleep_queue); |
} |
if (t->state == Sleeping) |
printf(" %#10zx %#10zx", t->kstack, t->sleep_queue); |
printf("\n"); |
} |
} |
573,6 → 596,22 |
return btree_search(&threads_btree, (btree_key_t) ((uintptr_t) t), &leaf) != NULL; |
} |
/** Update accounting of current thread. |
* |
* 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) |
{ |
uint64_t time = get_cycle(); |
THREAD->cycles += time - THREAD->last_cycle; |
THREAD->last_cycle = time; |
} |
/** Process syscall to create new thread. |
* |
*/ |