diff --git a/arch/aarch64.c b/arch/aarch64.c index ba8436b..0fd1d87 100644 --- a/arch/aarch64.c +++ b/arch/aarch64.c @@ -294,4 +294,82 @@ ssize_t recvfrom(int sockfd, const void* buf, size_t size, int flags, const void return rtn; } + +int clock_settime(clockid_t clockid, const struct timespec *tp) { + long int rtn; + asm volatile ( + // Assembly Instructions + "mov x8, #112\n" // Syscall number for 'listen' is 201 in AArch64 + "mov x0, %1\n" // fd + "mov x1, %2\n" // backlog + "svc #0\n" // Make the syscall + "mov %0, x0\n" // save return value + // Output operands + : "=r" (rtn) + // Input operand + : "r" ((int64_t)clockid), "r"(tp) + // Clobbered registers + : "x0", "x1", "x8" + ); + return (int32_t)rtn; +} + +int clock_gettime(clockid_t clockid, struct timespec *tp) { + long int rtn; + asm volatile ( + // Assembly Instructions + "mov x8, #113\n" // Syscall number for 'listen' is 201 in AArch64 + "mov x0, %1\n" // fd + "mov x1, %2\n" // backlog + "svc #0\n" // Make the syscall + "mov %0, x0\n" // save return value + // Output operands + : "=r" (rtn) + // Input operand + : "r" ((int64_t)clockid), "r"(tp) + // Clobbered registers + : "x0", "x1", "x8", "memory" + ); + return (int32_t)rtn; +} + +int clock_getres(clockid_t clockid, struct timespec *res) { + long int rtn; + asm volatile ( + // Assembly Instructions + "mov x8, #114\n" // Syscall number for 'listen' is 201 in AArch64 + "mov x0, %1\n" // fd + "mov x1, %2\n" // backlog + "svc #0\n" // Make the syscall + "mov %0, x0\n" // save return value + // Output operands + : "=r" (rtn) + // Input operand + : "r" ((int64_t)clockid), "r"(res) + // Clobbered registers + : "x0", "x1", "x8", "memory" + ); + return (int32_t)rtn; +} + +int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec* remain) { + long int rtn; + asm volatile ( + // Assembly Instructions + "mov x8, #115\n" // Syscall number for 'listen' is 201 in AArch64 + "mov x0, %1\n" // fd + "mov x1, %2\n" // backlog + "mov x2, %3\n" // backlog + "svc #0\n" // Make the syscall + "mov %0, x0\n" // save return value + // Output operands + : "=r" (rtn) + // Input operand + : "r" ((int64_t)clockid), "r"((int64_t)flags), "r"(t), "r"(remain) + // Clobbered registers + : "x0", "x1", "x8", "memory" + ); + return (int32_t)rtn; +} + #endif diff --git a/arch/mips.c b/arch/mips.c index 0ef5e37..4d5f52a 100644 --- a/arch/mips.c +++ b/arch/mips.c @@ -242,4 +242,63 @@ ssize_t recvfrom(int sockfd, const void* buf, size_t size, int flags, const void return rtn; } +int clock_settime(clockid_t clockid, const struct timespec *tp){ + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "li $v0, 4262\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(clockid), "r"(tp) + : "a0", "a1", "v0" + ); + return rtn; +} +int clock_gettime(clockid_t clockid, struct timespec *tp){ + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "li $v0, 4263\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(clockid), "r"(tp) + : "a0", "a1", "v0", "memory" + ); + return rtn; +} +int clock_getres(clockid_t clockid, struct timespec *res){ + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "li $v0, 4264\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(clockid), "r"(res) + : "a0", "a1", "v0", "memory" + ); + return rtn; +} +int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec* remain){ + int rtn = 0; + asm volatile ( + "move $a0, %1\n" + "move $a1, %2\n" + "move $a2, %3\n" + "move $a3, %4\n" + "li $v0, 4265\n" + "syscall\n" + "move %0, $v0\n" + : "=r"(rtn) + : "r"(clockid), "r"(flags), "r"(t), "r"(remain) + : "a0", "a1", "a2", "a3", "v0", "memory" + ); + return rtn; +} + #endif diff --git a/arch/x86_64.c b/arch/x86_64.c index 28378c8..24c4f4c 100644 --- a/arch/x86_64.c +++ b/arch/x86_64.c @@ -192,4 +192,53 @@ ssize_t recvfrom(int fd, const void* buf, size_t size, int flags, const void* so return nrecv; } +#define SYS_CLOCK_SETTIME 227 +int clock_settime(clockid_t clockid, const struct timespec *tp) { + int rtn; + asm volatile( + "syscall\n" + : "=a"(rtn) + : "a"(SYS_CLOCK_SETTIME), "D"(clockid), "S"(tp) + : "rcx", "r11" + ); + return rtn; +} + +#define SYS_CLOCK_GETTIME 228 +int clock_gettime(clockid_t clockid, struct timespec *tp) { + int rtn; + asm volatile( + "syscall\n" + : "=a"(rtn) + : "a"(SYS_CLOCK_GETTIME), "D"(clockid), "S"(tp) + : "rcx", "r11", "memory" + ); + return rtn; +} + +#define SYS_CLOCK_GETRES 229 +int clock_getres(clockid_t clockid, struct timespec *res){ + int rtn; + asm volatile( + "syscall\n" + : "=a"(rtn) + : "a"(SYS_CLOCK_GETRES), "D"(clockid), "S"(res) + : "rcx", "r11", "memory" + ); + return rtn; +} + +#define SYS_CLOCK_NANOSLEEP 230 +int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec* remain){ + int rtn; + asm volatile( + "mov %5, %%r10\n" + "syscall\n" + : "=a"(rtn) + : "a"(SYS_CLOCK_NANOSLEEP), "D"(clockid), "S"(flags), "d"(t), "r"(remain) + : "rcx", "r11", "memory" + ); + return rtn; +} + #endif /* ifdef __x86_64__ */ diff --git a/buildtest.c b/buildtest.c index 17bed6c..f439db2 100644 --- a/buildtest.c +++ b/buildtest.c @@ -50,6 +50,14 @@ int main() { } else { write(STDOUT, "Could not open /proc/version\n", 29); } + + // Test sleep + write(STDOUT, "Sleeping for 5 secs\n", 20); + struct timespec sleeptime; + sleeptime.tv_sec = 5; + while (nanosleep(&sleeptime, &sleeptime) != 0) {} + write(STDOUT, "DONE\n", 5); + return 69; } diff --git a/int.h b/int.h index caf7cf6..7c03f86 100644 --- a/int.h +++ b/int.h @@ -33,6 +33,13 @@ typedef uintptr_t size_t; typedef uint32_t socklen_t; typedef uint32_t pid_t; +typedef long time_t; +typedef int clockid_t; +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; + // Compile time tests in supported compilers #ifdef __SIZEOF_SHORT__ #if __SIZEOF_SHORT__ != 2 diff --git a/sys.h b/sys.h index c2781bc..2405368 100644 --- a/sys.h +++ b/sys.h @@ -128,9 +128,22 @@ typedef unsigned short sa_family_t; #define SO_PASSCRED 17 #define SO_PEERCRED 18 +// Time management +#define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 +#define TIMER_ABSTIME 0x01 +int clock_settime(clockid_t clockid, const struct timespec *tp); +int clock_gettime(clockid_t clockid, struct timespec *tp); +int clock_getres(clockid_t clockid, struct timespec *res); +int clock_nanosleep(clockid_t clockid, int flags, const struct timespec *t, struct timespec* remain); +#define nanosleep(t, remain) clock_nanosleep(CLOCK_MONOTONIC, 0, t, remain) + uint32_t fork(); // Provide memset for clang +// TODO: move this (and start code?) to separate .c file void *memset(void* s, int c, unsigned long n) { int8_t* mem = s; for(long int i = 0; i < n; ++i) mem[i] = c;