poll: timeout

This commit is contained in:
Matheus
2023-07-09 18:11:53 -03:00
parent e1776a71e5
commit 2398dd9b80
3 changed files with 31 additions and 8 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ typedef struct polldata {
int poll_initdesc(polldesc_t *, size_t size);
void poll_add(pollheader_t *, polldata_t *, int events);
void poll_leave(polldesc_t *);
int poll_dowait(polldesc_t *);
int poll_dowait(polldesc_t *, size_t ustimeout);
void poll_event(pollheader_t *, int events);
void poll_destroydesc(polldesc_t *);
+28 -1
View File
@@ -64,7 +64,20 @@ void poll_leave(polldesc_t *desc) {
}
}
int poll_dowait(polldesc_t *desc) {
static void timeout(context_t *, dpcarg_t arg) {
polldesc_t *desc = arg;
MUTEX_TRY(&desc->eventlock);
if (spinlock_try(&desc->lock))
sched_wakeup(desc->thread, 1);
MUTEX_RELEASE(&desc->eventlock);
}
int poll_dowait(polldesc_t *desc, size_t ustimeout) {
timerentry_t sleepentry = {0};
MUTEX_ACQUIRE(&desc->eventlock, false);
if (desc->event) {
MUTEX_RELEASE(&desc->eventlock);
@@ -72,12 +85,26 @@ int poll_dowait(polldesc_t *desc) {
}
sched_preparesleep(true);
if (ustimeout != 0) {
sched_targetcpu(_cpu());
timer_insert(_cpu()->timer, &sleepentry, timeout, desc, ustimeout, false);
}
spinlock_release(&desc->lock);
MUTEX_RELEASE(&desc->eventlock);
int ret = sched_yield();
// on return, the desc lock is REQUIRED to be left locked by the poll_event function.
// XXX interruptible wait breaks this
__assert(spinlock_try(&desc->lock) == false);
if (ustimeout != 0 && ret != 1) {
timer_remove(_cpu()->timer, &sleepentry);
sched_targetcpu(NULL);
}
ret = ret == 1 ? 0 : ret;
return ret;
}
+2 -6
View File
@@ -16,9 +16,6 @@ syscallret_t syscall_poll(context_t *, pollfd_t *fds, size_t nfds, int timeoutms
.ret = -1
};
// timeouts are not supported yet
__assert(timeoutms <= 0);
if ((void *)fds > USERSPACE_END) {
ret.errno = EFAULT;
return ret;
@@ -60,9 +57,8 @@ syscallret_t syscall_poll(context_t *, pollfd_t *fds, size_t nfds, int timeoutms
}
if (eventcount == 0 && timeoutms != 0) {
// TODO timeout
ret.errno = poll_dowait(&desc);
if (ret.errno == 0) {
ret.errno = poll_dowait(&desc, (timeoutms == -1 ? 0 : timeoutms) * 1000);
if (ret.errno == 0 && desc.event) {
int fd = ((uintptr_t)desc.event - (uintptr_t)desc.data) / sizeof(pollfd_t);
fdsbuff[fd].revents = desc.data[fd].revents;
eventcount = 1;