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:
parent
5d0cf35f4f
commit
f3b620a9be
10 changed files with 68 additions and 13 deletions
|
@ -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
|
||||
|
|
|
@ -49,6 +49,7 @@ extern "C" {
|
|||
#define __NR_fork 12
|
||||
#define __NR_wait 13
|
||||
#define __NR_execve 14
|
||||
#define __NR_times 15
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) " "
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue