Sixty-five headers sat side by side in include/, so `#include "irq.h"` said nothing about where irq.h was or what it belonged to, and errno.h, stat.h and fcntl.h at the top shadowed the system's for any host tool built with -I./include. They are in folders now -- arch/ core/ fs/ dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and every include names the folder, as Linux's do: "core/proc.h". Done mechanically and checked the hard way: the kernel built from this tree disassembles identically to the one built from the tree before it. The full image boots, and userland is the same set of programs. Paths in docs and comments follow; docs/guides/layout.md has a table of what is where, and tools/fix-includes.py rewrites old-style includes from the folders in the tree, for code written before this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
139 lines
3.4 KiB
C
139 lines
3.4 KiB
C
#include "core/types.h"
|
|
#include "core/defs.h"
|
|
#include "core/param.h"
|
|
#include "core/date.h"
|
|
#include "core/spinlock.h"
|
|
#include "core/proc.h"
|
|
#include "arch/x86.h"
|
|
#include "core/syscall.h"
|
|
#include "uapi/posix.h"
|
|
#include "core/uaccess.h"
|
|
#include "uapi/errno.h"
|
|
|
|
addr_t
|
|
sys_alarm(void)
|
|
{
|
|
int seconds;
|
|
if (argint(0, &seconds) < 0)
|
|
return -1;
|
|
myproc()->alarm_ticks = seconds * HZ;
|
|
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 * HZ)) {
|
|
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 * HZ +
|
|
iv.it_value.tv_usec / USEC_PER_TICK);
|
|
}
|
|
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 * HZ)) {
|
|
if (myproc()->killed) { release(&tickslock); return -EINTR; }
|
|
sleep(&ticks, &tickslock);
|
|
}
|
|
release(&tickslock);
|
|
}
|
|
return 0;
|
|
}
|