add rudimental support of the system call times

- no full support of the POSIX API
- however, the libc function clock works correctly
This commit is contained in:
Stefan Lankes 2011-04-21 10:13:58 +02:00
parent 5d0cf35f4f
commit f3b620a9be
10 changed files with 68 additions and 13 deletions

View file

@ -22,6 +22,7 @@
#include <metalsvm/tasks.h>
#include <metalsvm/time.h>
#include <metalsvm/processor.h>
#include <metalsvm/errno.h>
#include <asm/irq.h>
#include <asm/irqflags.h>
#include <asm/gdt.h>
@ -39,6 +40,19 @@ uint64_t get_clock_tick(void)
return timer_ticks;
}
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;
}
/*
* Handles the timer. In this case, it's very simple: We
* increment the 'timer_ticks' variable every time the

View file

@ -49,6 +49,7 @@ extern "C" {
#define __NR_fork 12
#define __NR_wait 13
#define __NR_execve 14
#define __NR_times 15
#ifdef __cplusplus
}

View file

@ -72,6 +72,8 @@ typedef struct task {
vma_t* vma_list;
/// Additional status flags. For instance, to signalize the using of the FPU
uint32_t flags;
/// starting time/tick of the task
uint64_t start_tick;
/// Start address of the heap
uint32_t start_heap;
/// End address of the heap

View file

@ -30,6 +30,26 @@
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 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 Initialize Timer interrupts
*
* This procedure installs IRQ handlers for timer interrupts

View file

@ -23,6 +23,7 @@
#include <metalsvm/tasks.h>
#include <metalsvm/errno.h>
#include <metalsvm/spinlock.h>
#include <metalsvm/time.h>
static int sys_write(int fildes, const char *buf, size_t len)
{
@ -105,7 +106,7 @@ int syscall_handler(uint32_t sys_nr, ...)
break;
case __NR_wait: {
int32_t* status = va_arg(vl, int32_t*);
ret = wait(status);
break;
}
@ -117,6 +118,13 @@ int syscall_handler(uint32_t sys_nr, ...)
ret = sys_execve(name, argv, env);
break;
}
case __NR_times: {
struct tms* buffer = va_arg(vl, struct tms*);
clock_t* clock = va_arg(vl, clock_t*);
ret = sys_times(buffer, clock);
break;
}
default:
kputs("invalid system call\n");
ret = -ENOSYS;

View file

@ -38,6 +38,7 @@
#include <metalsvm/mailbox.h>
#include <metalsvm/syscall.h>
#include <metalsvm/fs.h>
#include <metalsvm/time.h>
#include <asm/apic.h>
#include <asm/elf.h>
@ -48,7 +49,7 @@ DEFINE_PER_CORE(task_t*, current_task, NULL);
* A task's id will be its position in this array.
*/
static task_t task_table[MAX_TASKS] = {[0 ... MAX_TASKS-1] = {0, TASK_INVALID, ATOMIC_INIT(0), \
SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0}};
SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0, 0}};
static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT;
/** @brief helper function for the assembly code to determine the current task
@ -193,6 +194,7 @@ static int create_task(tid_t* id, entry_point_t ep, void* arg)
task_table[i].flags = TASK_DEFAULT_FLAGS;
task_table[i].start_heap = 0;
task_table[i].end_heap = 0;
task_table[i].start_tick = get_clock_tick();
task_table[i].status = TASK_READY;
break;
}
@ -256,6 +258,7 @@ int sys_fork(void)
task_table[i].outbox[per_core(current_task)->id] = &per_core(current_task)->inbox;
task_table[i].flags = per_core(current_task)->flags;
memcpy(&(task_table[i].fpu), &(per_core(current_task)->fpu), sizeof(union fpu_state));
task_table[i].start_tick = get_clock_tick();
task_table[i].start_heap = 0;
task_table[i].end_heap = 0;

View file

@ -113,8 +113,8 @@ int test_init(void)
//create_kernel_task(NULL, producer, NULL);
//create_kernel_task(NULL, consumer, NULL);
//create_user_task(NULL, "/bin/hello", argv);
create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
//create_user_task(NULL, "/bin/tests", argv);
create_user_task(NULL, "/bin/jacobi", argv);
return 0;
}

View file

@ -96,7 +96,7 @@ int main(int argc, char **argv)
double** A=0;
double* X;
double* X_old, xi;
double start,stop;
clock_t start, end;
if (generate_empty_matrix(&A,MATRIX_SIZE) < 0)
{
@ -126,7 +126,7 @@ int main(int argc, char **argv)
iter_start = 0;
iter_end = MATRIX_SIZE;
//start = RCCE_wtime();
start = clock();
while(1)
{
@ -158,7 +158,7 @@ int main(int argc, char **argv)
}
}
//stop = RCCE_wtime();
end = clock();
if (MATRIX_SIZE < 16) {
printf("Print the solution...\n");
@ -187,7 +187,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", stop-start);
printf("calculation time: %f s\n", (float) (end-start) / (float) CLOCKS_PER_SEC);
free((void*) X_old);
free((void*) X);

View file

@ -38,6 +38,7 @@ extern "C" {
#define __NR_fork 12
#define __NR_wait 13
#define __NR_execve 14
#define __NR_times 15
#define _STR(token) #token
#define _SYSCALLSTR(x) "int $" _STR(x) " "

View file

@ -24,14 +24,20 @@
#include <errno.h>
#undef errno
extern int errno;
#include "warning.h"
#include "syscall.h"
clock_t
_DEFUN (_times, (buf),
struct tms *buf)
{
errno = ENOSYS;
return -1;
}
clock_t clock = 0;
int ret;
stub_warning(_times)
ret = SYSCALL2(__NR_times, buf, &clock);
if (ret < 0) {
errno = -ret;
return (clock_t) -1;
}
return clock;
}