futex: fix issues that prevented it from working properly

This commit is contained in:
Matheus
2022-12-31 18:15:46 -03:00
parent 2f28713dae
commit 5d62629d6f
+14 -6
View File
@@ -6,6 +6,7 @@
#include <arch/interrupt.h> #include <arch/interrupt.h>
#include <kernel/alloc.h> #include <kernel/alloc.h>
#include <arch/timekeeper.h> #include <arch/timekeeper.h>
#include <arch/cls.h>
#include <time.h> #include <time.h>
#define FUTEX_WAIT 0 #define FUTEX_WAIT 0
@@ -35,9 +36,10 @@ static inline futex_t* getfutex(void *addr){
} }
static inline void setfutex(futex_t* futex){ static inline void setfutex(futex_t* futex, void* paddr){
futex->next = first; futex->next = first;
first = futex; first = futex;
futex->phyaddr = paddr;
} }
syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct timespec* tm){ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct timespec* tm){
@@ -51,11 +53,11 @@ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct times
} }
uint32_t word; uint32_t word;
__atomic_load(futex, &word, __ATOMIC_RELAXED);
spinlock_acquire(&lock); spinlock_acquire(&lock);
__atomic_load(futex, &word, __ATOMIC_RELAXED); // TODO copy from userspace with u_memcpy
// TODO safer way of getting the address from userspace while inside the lock // TODO safer way of getting the address from userspace while inside the lock
uint32_t* phyfutex = vmm_tophysical(futex); uint32_t* phyfutex = vmm_tophysical(futex);
@@ -73,7 +75,6 @@ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct times
retv.ret = v > f->waitercount ? f->waitercount : v; retv.ret = v > f->waitercount ? f->waitercount : v;
f->waitercount -= retv.ret; f->waitercount -= retv.ret;
f->waitersleft += retv.ret; f->waitersleft += retv.ret;
@@ -92,7 +93,7 @@ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct times
retv.errno = ENOMEM; retv.errno = ENOMEM;
break; break;
} }
setfutex(f); setfutex(f, phyfutex);
} }
struct timespec target = arch_timekeeper_gettime(); struct timespec target = arch_timekeeper_gettime();
@@ -108,6 +109,10 @@ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct times
// XXX probably should use events here // XXX probably should use events here
++f->waitercount;
spinlock_release(&lock);
for(;;){ for(;;){
if(spinlock_trytoacquire(&lock)){ if(spinlock_trytoacquire(&lock)){
@@ -139,6 +144,9 @@ syscallret syscall_futex(uint32_t *futex, int op, uint32_t v, const struct times
} }
if(f->waitercount == 0 && f->waitersleft == 0)
free(f);
retv.ret = 0; retv.ret = 0;
retv.errno = 0; retv.errno = 0;
break; break;