Initial commit: Schunix as it stands before the SchOS rename
An x86-64 operating system built from xv6, now largely rewritten: SMP, a copy-on-write root filesystem (SchFS), PCI/USB/virtio drivers, a TTF rasteriser, and a Linux-numbered syscall ABI. No history before this point -- the tree was never under version control. This commit exists so the rename that follows has something to undo to.
This commit is contained in:
commit
d0f7acf9eb
275 changed files with 51417 additions and 0 deletions
139
kernel/sys/sys_time.c
Normal file
139
kernel/sys/sys_time.c
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#include "types.h"
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "date.h"
|
||||
#include "spinlock.h"
|
||||
#include "proc.h"
|
||||
#include "x86.h"
|
||||
#include "syscall.h"
|
||||
#include "posix.h"
|
||||
#include "uaccess.h"
|
||||
#include "errno.h"
|
||||
|
||||
addr_t
|
||||
sys_alarm(void)
|
||||
{
|
||||
int seconds;
|
||||
if (argint(0, &seconds) < 0)
|
||||
return -1;
|
||||
myproc()->alarm_ticks = seconds * 100;
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_gettimeofday(void)
|
||||
{
|
||||
struct timeval *tv;
|
||||
if (argptr(0, (char**)&tv, sizeof(*tv)) < 0)
|
||||
return -1;
|
||||
if (tv) {
|
||||
// Real time, from the hardware clock read at boot plus uptime -- not
|
||||
// uptime alone, which is what this used to return and why every machine
|
||||
// thought it was 1970. See kernel/core/time.c.
|
||||
uint64 sec, usec;
|
||||
wallclock(&sec, &usec);
|
||||
tv->tv_sec = (long)sec;
|
||||
tv->tv_usec = (long)usec;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_nanosleep(void)
|
||||
{
|
||||
addr_t tsaddr, raw;
|
||||
if (argaddr(0, &tsaddr) < 0 || fetchaddr(tsaddr, &raw) < 0)
|
||||
return -1;
|
||||
int64 sec = (int64)raw;
|
||||
if (sec > 0) {
|
||||
acquire(&tickslock);
|
||||
uint t0 = ticks;
|
||||
while (ticks - t0 < (uint)(sec * 100)) {
|
||||
if (myproc()->killed) { release(&tickslock); return -EINTR; }
|
||||
sleep(&ticks, &tickslock);
|
||||
}
|
||||
release(&tickslock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_clock_gettime(void)
|
||||
{
|
||||
int clkid;
|
||||
struct timespec *tp;
|
||||
argint(0, &clkid);
|
||||
if (argptr(1, (char**)&tp, sizeof(*tp)) < 0)
|
||||
return -1;
|
||||
// CLOCK_MONOTONIC (1) counts from boot; everything else is treated as a
|
||||
// realtime clock and counts from the epoch. Returning boot-relative values
|
||||
// for CLOCK_REALTIME is what made timestamps land in 1970.
|
||||
uint64 sec, usec;
|
||||
wallclock(&sec, &usec);
|
||||
if (clkid == 1)
|
||||
sec -= boot_epoch;
|
||||
tp->tv_sec = (long)sec;
|
||||
tp->tv_nsec = (long)(usec * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t sys_getitimer(void) { return 0; } // stub
|
||||
|
||||
addr_t
|
||||
sys_setitimer(void)
|
||||
{
|
||||
int which;
|
||||
addr_t newp;
|
||||
argint(0, &which); argaddr(1, &newp);
|
||||
// We don't implement interval timers; just track the alarm if it's ITIMER_REAL.
|
||||
if (which == 0 && newp) {
|
||||
struct itimerval iv;
|
||||
if (copy_from_user(&iv, newp, sizeof(iv)) == 0)
|
||||
myproc()->alarm_ticks = (int)(iv.it_value.tv_sec * 100 +
|
||||
iv.it_value.tv_usec / 10000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_time(void)
|
||||
{
|
||||
addr_t tloc;
|
||||
argaddr(0, &tloc);
|
||||
uint64 sec;
|
||||
wallclock(&sec, 0);
|
||||
long t = (long)sec;
|
||||
if (tloc)
|
||||
put_user(t, tloc);
|
||||
return (addr_t)t;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_clock_getres(void)
|
||||
{
|
||||
struct timespec *tp;
|
||||
if (argptr(1, (char**)&tp, sizeof(*tp)) < 0) return 0;
|
||||
if (tp) { tp->tv_sec = 0; tp->tv_nsec = 10000000L; } // 10ms resolution
|
||||
return 0;
|
||||
}
|
||||
|
||||
addr_t
|
||||
sys_clock_nanosleep(void)
|
||||
{
|
||||
// Treat the same as nanosleep: arg2 is the timespec, arg1 is flags.
|
||||
// Linux: clock_nanosleep(clockid, flags, rqtp, rmtp)
|
||||
addr_t tsaddr, raw;
|
||||
if (argaddr(2, &tsaddr) < 0 || fetchaddr(tsaddr, &raw) < 0)
|
||||
return -1;
|
||||
int64 sec = (int64)raw;
|
||||
if (sec > 0) {
|
||||
acquire(&tickslock);
|
||||
uint t0 = ticks;
|
||||
while (ticks - t0 < (uint)(sec * 100)) {
|
||||
if (myproc()->killed) { release(&tickslock); return -EINTR; }
|
||||
sleep(&ticks, &tickslock);
|
||||
}
|
||||
release(&tickslock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue