mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-29 21:58:20 +00:00
syscalls: fchdir, setitimer, getitimer
This commit is contained in:
@@ -42,3 +42,27 @@ syscallret_t syscall_chdir(context_t *, const char *upath) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
syscallret_t syscall_fchdir(context_t *, int fd) {
|
||||
syscallret_t ret = {
|
||||
.ret = -1
|
||||
};
|
||||
|
||||
file_t *file = fd_get(fd);
|
||||
if (file == NULL) {
|
||||
ret.errno = EBADF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (file->vnode->type != V_TYPE_DIR) {
|
||||
ret.errno = ENOTDIR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sched_setcwd(file->vnode);
|
||||
ret.errno = 0;
|
||||
|
||||
cleanup:
|
||||
fd_release(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,9 @@ syscallret_t syscall_futex(context_t *, uint32_t *futexp, int op, uint32_t value
|
||||
MUTEX_RELEASE(&futexmutex);
|
||||
|
||||
ret.errno = poll_dowait(&desc, us);
|
||||
int revents = desc.event->revents;
|
||||
int revents = 0;
|
||||
if (desc.event)
|
||||
revents = desc.event->revents;
|
||||
|
||||
MUTEX_ACQUIRE(&futexmutex, false);
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
#include <kernel/syscalls.h>
|
||||
#include <time.h>
|
||||
#include <kernel/scheduler.h>
|
||||
#include <logging.h>
|
||||
|
||||
#define ITIMER_REAL 0
|
||||
#define ITIMER_VIRTUAL 1
|
||||
#define ITIMER_PROF 2
|
||||
|
||||
typedef struct {
|
||||
timeval_t interval;
|
||||
timeval_t value;
|
||||
} itimerval_t;
|
||||
|
||||
static itimer_t *selectitimer(int which) {
|
||||
itimer_t *itimer = NULL;
|
||||
if (which == ITIMER_REAL)
|
||||
itimer = &_cpu()->thread->proc->timer.realtime;
|
||||
else if (which == ITIMER_VIRTUAL)
|
||||
itimer = &_cpu()->thread->proc->timer.virtualtime;
|
||||
else if (which == ITIMER_PROF)
|
||||
itimer = &_cpu()->thread->proc->timer.profiling;
|
||||
|
||||
return itimer;
|
||||
}
|
||||
|
||||
syscallret_t syscall_getitimer(context_t *context, int which, itimerval_t *value) {
|
||||
syscallret_t ret = {
|
||||
.ret = -1
|
||||
};
|
||||
|
||||
__assert(which == ITIMER_REAL);
|
||||
itimer_t *itimer = selectitimer(which);
|
||||
if (itimer == NULL) {
|
||||
ret.errno = EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
MUTEX_ACQUIRE(&_cpu()->thread->proc->timer.mutex, false);
|
||||
|
||||
uintmax_t oldremaining, oldrepeat;
|
||||
itimer_pause(itimer, &oldremaining, &oldrepeat);
|
||||
if (oldremaining)
|
||||
itimer_resume(itimer);
|
||||
|
||||
MUTEX_RELEASE(&_cpu()->thread->proc->timer.mutex);
|
||||
|
||||
value->interval.s = oldrepeat / 1000000;
|
||||
value->interval.us = oldrepeat % 1000000;
|
||||
value->value.s = oldremaining / 1000000;
|
||||
value->value.us = oldremaining % 1000000;
|
||||
ret.errno = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
syscallret_t syscall_setitimer(context_t *context, int which, itimerval_t *unew, itimerval_t *uold) {
|
||||
syscallret_t ret = {
|
||||
.ret = -1
|
||||
};
|
||||
|
||||
__assert(which == ITIMER_REAL);
|
||||
|
||||
itimer_t *itimer = selectitimer(which);
|
||||
if (itimer == NULL) {
|
||||
ret.errno = EINVAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
itimerval_t val = {0};
|
||||
if (unew)
|
||||
val = *unew;
|
||||
|
||||
MUTEX_ACQUIRE(&_cpu()->thread->proc->timer.mutex, false);
|
||||
uintmax_t oldremaining, oldrepeat;
|
||||
itimer_pause(itimer, &oldremaining, &oldrepeat);
|
||||
|
||||
// TODO overflow check
|
||||
uintmax_t repeatus = val.interval.s * 1000000 + val.interval.us;
|
||||
uintmax_t newus = val.value.s * 1000000 + val.value.us;
|
||||
itimer_set(itimer, newus, repeatus);
|
||||
|
||||
if (newus)
|
||||
itimer_resume(itimer);
|
||||
|
||||
MUTEX_RELEASE(&_cpu()->thread->proc->timer.mutex);
|
||||
|
||||
if (uold) {
|
||||
uold->interval.s = oldrepeat / 1000000;
|
||||
uold->interval.us = oldrepeat % 1000000;
|
||||
uold->value.s = oldremaining / 1000000;
|
||||
uold->value.us = oldremaining % 1000000;
|
||||
}
|
||||
|
||||
ret.errno = 0;
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user