Second Extended Filesystem (ext2) and other improvements (#33)
[lunaix-os.git] / lunaix-os / kernel / device / poll.c
index e7f0f876a909ee602b17ce32d51b2067030f7bd2..159c2bb87cffb896cb6312220fb5cae6421df978 100644 (file)
@@ -7,13 +7,14 @@
 #include <lunaix/spike.h>
 #include <lunaix/syscall.h>
 #include <lunaix/syscall_utils.h>
+#include <lunaix/kpreempt.h>
 
 #define MAX_POLLER_COUNT 16
 
 static inline void
 current_rmiopoll(int pld)
 {
-    iopoll_remove(__current->pid, &__current->pollctx, pld);
+    iopoll_remove(current_thread, pld);
 }
 
 static struct iopoller*
@@ -37,7 +38,7 @@ __do_poll(struct poll_info* pinfo, int pld)
     struct device* dev;
     int evt = 0;
 
-    if ((dev = device_cast(poller->file_ref->inode->data))) {
+    if ((dev = resolve_device(poller->file_ref->inode->data))) {
         dev->ops.poll(dev);
     } else {
         // TODO handle generic file
@@ -111,7 +112,7 @@ __do_poll_all(struct poll_info* pinfo)
     return 0;
 }
 
-#define fd2dev(fd) device_cast((fd)->file->inode->data)
+#define fd2dev(fd) resolve_device((fd)->file->inode->data)
 
 static int
 __alloc_pld()
@@ -138,7 +139,7 @@ __append_pollers(int* ds, int npoller)
             continue;
         }
 
-        int pld = iopoll_install(__current->pid, &__current->pollctx, fd_s);
+        int pld = iopoll_install(current_thread, fd_s);
         if (pld < 0) {
             nc++;
         }
@@ -149,23 +150,25 @@ __append_pollers(int* ds, int npoller)
     return nc;
 }
 
-static int
+static void
 __wait_until_event()
 {
-    block_current();
-    sched_yieldk();
+    block_current_thread();
+    yield_current();
 }
 
 void
 iopoll_init(struct iopoll* ctx)
 {
-    ctx->pollers = valloc(sizeof(ptr_t) * MAX_POLLER_COUNT);
+    ctx->pollers = vzalloc(sizeof(ptr_t) * MAX_POLLER_COUNT);
     ctx->n_poller = 0;
 }
 
 void
-iopoll_free(pid_t pid, struct iopoll* ctx)
+iopoll_free(struct proc_info* proc)
 {
+    pid_t pid = proc->pid;
+    struct iopoll* ctx = &proc->pollctx;
     for (int i = 0; i < MAX_POLLER_COUNT; i++) {
         struct iopoller* poller = ctx->pollers[i];
         if (poller) {
@@ -173,9 +176,9 @@ iopoll_free(pid_t pid, struct iopoll* ctx)
             llist_delete(&poller->evt_listener);
             vfree(poller);
         }
-
-        vfree(ctx->pollers);
     }
+    
+    vfree(ctx->pollers);
 }
 
 void
@@ -184,24 +187,27 @@ iopoll_wake_pollers(poll_evt_q* pollers_q)
     struct iopoller *pos, *n;
     llist_for_each(pos, n, pollers_q, evt_listener)
     {
-        struct proc_info* proc = get_process(pos->pid);
-        if (proc_hanged(proc)) {
-            resume_process(proc);
+        struct thread* thread = pos->thread;
+        assert(!proc_terminated(thread));
+        
+        if (proc_hanged(thread)) {
+            resume_thread(thread);
         }
-
-        assert(!proc_terminated(proc));
     }
 }
 
 int
-iopoll_remove(pid_t pid, struct iopoll* ctx, int pld)
+iopoll_remove(struct thread* thread, int pld)
 {
+    struct proc_info* proc = thread->process;
+    struct iopoll* ctx = &proc->pollctx;
     struct iopoller* poller = ctx->pollers[pld];
     if (!poller) {
         return ENOENT;
     }
 
-    vfs_pclose(poller->file_ref, pid);
+    // FIXME vfs locking model need to rethink in the presence of threads
+    vfs_pclose(poller->file_ref, proc->pid);
     vfree(poller);
     ctx->pollers[pld] = NULL;
     ctx->n_poller--;
@@ -210,7 +216,7 @@ iopoll_remove(pid_t pid, struct iopoll* ctx, int pld)
 }
 
 int
-iopoll_install(pid_t pid, struct iopoll* pollctx, struct v_fd* fd)
+iopoll_install(struct thread* thread, struct v_fd* fd)
 {
     int pld = __alloc_pld();
     if (pld < 0) {
@@ -220,12 +226,14 @@ iopoll_install(pid_t pid, struct iopoll* pollctx, struct v_fd* fd)
     struct iopoller* iop = valloc(sizeof(struct iopoller));
     *iop = (struct iopoller){
         .file_ref = fd->file,
-        .pid = pid,
+        .thread = thread,
     };
 
     vfs_ref_file(fd->file);
-    __current->pollctx.pollers[pld] = iop;
-    __current->pollctx.n_poller++;
+
+    struct proc_info* proc = thread->process;
+    proc->pollctx.pollers[pld] = iop;
+    proc->pollctx.n_poller++;
 
     struct device* dev;
     if ((dev = fd2dev(fd))) {
@@ -237,9 +245,13 @@ iopoll_install(pid_t pid, struct iopoll* pollctx, struct v_fd* fd)
     return pld;
 }
 
-__DEFINE_LXSYSCALL2(int, pollctl, int, action, va_list, va)
+__DEFINE_LXSYSCALL2(int, pollctl, int, action, sc_va_list, _ap)
 {
     int retcode = 0;
+    va_list va;
+
+    convert_valist(&va, _ap);
+    
     switch (action) {
         case _SPOLL_ADD: {
             int* ds = va_arg(va, int*);
@@ -248,7 +260,7 @@ __DEFINE_LXSYSCALL2(int, pollctl, int, action, va_list, va)
         } break;
         case _SPOLL_RM: {
             int pld = va_arg(va, int);
-            retcode = iopoll_remove(__current->pid, &__current->pollctx, pld);
+            retcode = iopoll_remove(current_thread, pld);
         } break;
         case _SPOLL_WAIT: {
             struct poll_info* pinfos = va_arg(va, struct poll_info*);
@@ -257,7 +269,7 @@ __DEFINE_LXSYSCALL2(int, pollctl, int, action, va_list, va)
 
             time_t t1 = clock_systime() + timeout;
             while (!(retcode == __do_poll_round(pinfos, npinfos))) {
-                if (timeout >= 0 && t1 >= clock_systime()) {
+                if (timeout >= 0 && t1 < clock_systime()) {
                     break;
                 }
                 __wait_until_event();
@@ -269,7 +281,7 @@ __DEFINE_LXSYSCALL2(int, pollctl, int, action, va_list, va)
 
             time_t t1 = clock_systime() + timeout;
             while (!(retcode == __do_poll_all(pinfo))) {
-                if (timeout >= 0 && t1 >= clock_systime()) {
+                if (timeout >= 0 && t1 < clock_systime()) {
                     break;
                 }
                 __wait_until_event();