From cce69cfe44100c5e4c72aca916aef651f69ddd89 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Thu, 16 Jul 2015 22:33:29 +0200 Subject: [PATCH] add support of sys_times (=> clock()) --- hermit/arch/x86/kernel/timer.c | 14 ++++++++++++++ hermit/include/hermit/tasks_types.h | 2 ++ hermit/include/hermit/time.h | 20 ++++++++++++++++++++ hermit/kernel/main.c | 2 ++ hermit/kernel/syscall.c | 3 ++- hermit/kernel/tasks.c | 5 +++-- hermit/newlib/examples/jacobi.c | 8 ++++---- hermit/newlib/examples/stream.c | 17 +++++++++++++++++ 8 files changed, 64 insertions(+), 7 deletions(-) diff --git a/hermit/arch/x86/kernel/timer.c b/hermit/arch/x86/kernel/timer.c index f2e6c95d3..49022ab4f 100644 --- a/hermit/arch/x86/kernel/timer.c +++ b/hermit/arch/x86/kernel/timer.c @@ -42,6 +42,20 @@ static volatile uint64_t timer_ticks = 0; extern uint32_t cpu_freq; +int sys_times(struct tms* buffer, clock_t* clock) +{ + if (BUILTIN_EXPECT(!buffer, 0)) + return -EINVAL; + if (BUILTIN_EXPECT(!clock, 0)) + return -EINVAL; + + memset(buffer, 0x00, sizeof(struct tms)); + *clock = buffer->tms_utime = (clock_t) ((timer_ticks - per_core(current_task)->start_tick) * CLOCKS_PER_SEC / TIMER_FREQ); + + return 0; +} + + uint64_t get_clock_tick(void) { return timer_ticks; diff --git a/hermit/include/hermit/tasks_types.h b/hermit/include/hermit/tasks_types.h index 5c2a29587..20eb35daf 100644 --- a/hermit/include/hermit/tasks_types.h +++ b/hermit/include/hermit/tasks_types.h @@ -94,6 +94,8 @@ typedef struct task { spinlock_t vma_lock; /// list of VMAs vma_t* vma_list; + /// starting time/tick of the task + uint64_t start_tick; /// the userspace heap vma_t* heap; /// usage in number of pages (including page map tables) diff --git a/hermit/include/hermit/time.h b/hermit/include/hermit/time.h index d84f889f3..1b3e108d5 100644 --- a/hermit/include/hermit/time.h +++ b/hermit/include/hermit/time.h @@ -38,6 +38,20 @@ extern "C" { #endif +typedef uint32_t clock_t; + +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; + +#ifndef CLOCKS_PER_SEC +// newlib's default value +#define CLOCKS_PER_SEC 1000 +#endif + /** @brief Initialize Timer interrupts * * This procedure installs IRQ handlers for timer interrupts @@ -52,6 +66,12 @@ int timer_init(void); */ int timer_wait(unsigned int ticks); +/** @brief Determines the time in CLK_TCK's + * + * System call, which returns the value of time in CLK_TCK's + */ +int sys_times(struct tms*, clock_t* clock); + /** @brief Returns the current number of ticks. * @return Current number of ticks */ diff --git a/hermit/kernel/main.c b/hermit/kernel/main.c index e5ed6681e..d918480a8 100644 --- a/hermit/kernel/main.c +++ b/hermit/kernel/main.c @@ -140,12 +140,14 @@ static int initd(void* arg) { char* argv1[] = {"/bin/hello", NULL}; char* argv2[] = {"/bin/jacobi", NULL}; + char* argv3[] = {"/bin/stream", NULL}; //create_kernel_task(NULL, foo, "foo1", NORMAL_PRIO); //create_kernel_task(NULL, foo, "foo2", NORMAL_PRIO); create_user_task(NULL, "/bin/hello", argv1, NORMAL_PRIO); create_user_task(NULL, "/bin/jacobi", argv2, NORMAL_PRIO); create_user_task(NULL, "/bin/jacobi", argv2, NORMAL_PRIO); + //create_user_task(NULL, "/bin/stream", argv3, NORMAL_PRIO); #if 0 init_netifs(); diff --git a/hermit/kernel/syscall.c b/hermit/kernel/syscall.c index eae55cdcc..095346aaf 100644 --- a/hermit/kernel/syscall.c +++ b/hermit/kernel/syscall.c @@ -31,6 +31,7 @@ #include #include #include +#include static int sys_write(int fd, const char* buf, size_t len) { @@ -105,7 +106,7 @@ size_t syscall_table[] = { (size_t) default_handler, /* __NR_fork */ (size_t) default_handler, /* __NR_wait */ (size_t) default_handler, /* __NR_execve */ - (size_t) default_handler, /* __NR_times */ + (size_t) sys_times, /* __NR_times */ (size_t) default_handler, /* __NR_accept */ (size_t) default_handler, /* __NR_bind */ (size_t) default_handler, /* __NR_closesocket */ diff --git a/hermit/kernel/tasks.c b/hermit/kernel/tasks.c index d76ec8a4e..f7971ed32 100644 --- a/hermit/kernel/tasks.c +++ b/hermit/kernel/tasks.c @@ -42,8 +42,8 @@ * A task's id will be its position in this array. */ static task_t task_table[MAX_TASKS] = { \ - [0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, NULL, ATOMIC_INIT(0), NULL, NULL, 0}, \ - [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, NULL,ATOMIC_INIT(0), NULL, NULL, 0}}; + [0] = {0, TASK_IDLE, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, ATOMIC_INIT(0), NULL, NULL, 0}, \ + [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, NULL, NULL, TASK_DEFAULT_FLAGS, 0, 0, 0, SPINLOCK_IRQSAVE_INIT, SPINLOCK_INIT, NULL, 0, NULL, ATOMIC_INIT(0), NULL, NULL, 0}}; static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT; @@ -264,6 +264,7 @@ int create_task(tid_t* id, entry_point_t ep, void* arg, uint8_t prio, uint32_t c task_table[i].vma_list = NULL; task_table[i].heap = NULL; task_table[i].lwip_err = 0; + task_table[i].start_tick = get_clock_tick(); spinlock_irqsave_init(&task_table[i].page_lock); atomic_int32_set(&task_table[i].user_usage, 0); diff --git a/hermit/newlib/examples/jacobi.c b/hermit/newlib/examples/jacobi.c index 777ff69cc..9b57e95e3 100644 --- a/hermit/newlib/examples/jacobi.c +++ b/hermit/newlib/examples/jacobi.c @@ -107,7 +107,7 @@ int main(int argc, char **argv) double** A=0; double* X; double* X_old, xi; - //clock_t start, end; + clock_t start, end; if (generate_empty_matrix(&A,MATRIX_SIZE) < 0) { @@ -137,7 +137,7 @@ int main(int argc, char **argv) iter_start = 0; iter_end = MATRIX_SIZE; - //start = clock(); + start = clock(); while(1) { @@ -169,7 +169,7 @@ int main(int argc, char **argv) } } - //end = clock(); + end = clock(); if (MATRIX_SIZE < 16) { printf("Print the solution...\n"); @@ -200,7 +200,7 @@ int main(int argc, char **argv) printf("\nmatrix size: %d x %d\n", MATRIX_SIZE, MATRIX_SIZE); printf("number of iterations: %d\n", iterations); - //printf("calculation time: %f s\n", (float) (end-start) / (float) CLOCKS_PER_SEC); + printf("calculation time: %f s\n", (float) (end-start) / (float) CLOCKS_PER_SEC); free((void*) X_old); free((void*) X); diff --git a/hermit/newlib/examples/stream.c b/hermit/newlib/examples/stream.c index b9a2cee3b..5568dd362 100644 --- a/hermit/newlib/examples/stream.c +++ b/hermit/newlib/examples/stream.c @@ -415,16 +415,33 @@ checktick() /* A gettimeofday routine to give access to the wall clock timer on most UNIX-like systems. */ +#include #include double mysecond() { +#if 0 struct timeval tp; struct timezone tzp; int i; i = gettimeofday(&tp,&tzp); return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 ); +#else + static clock_t start, init = 0; + double ret; + + if (init) { + ret = (double) (clock() - start) / (double) CLOCKS_PER_SEC; + } else { + start = clock(); + init = 1; + ret = 0.0; + //printf("CLOCKS_PER_SEC = %d\n", CLOCKS_PER_SEC); + } + + return ret; +#endif } #ifndef abs