Support to multi-threading and pthread interface (POSIX.1-2008) (#23)
[lunaix-os.git] / lunaix-os / kernel / ds / waitq.c
index 0d643d02e7de3649d4da25d50c7b9d41258cc4c1..c9fb88f3fede01cffd78d3900e33027f05d28457 100644 (file)
@@ -1,18 +1,24 @@
 #include <lunaix/ds/waitq.h>
 #include <lunaix/process.h>
+#include <lunaix/sched.h>
 #include <lunaix/spike.h>
 
 void
 pwait(waitq_t* queue)
 {
-    waitq_t* current_wq = &__current->waitqueue;
+    assert(current_thread);
+    // prevent race condition.
+    cpu_disable_interrupt();
+
+    waitq_t* current_wq = &current_thread->waitqueue;
     assert(llist_empty(&current_wq->waiters));
 
     llist_append(&queue->waiters, &current_wq->waiters);
 
-    // FIXME centralize the state change.
-    __current->state = PS_BLOCKED;
-    sched_yieldk();
+    block_current_thread();
+    sched_pass();
+
+    cpu_enable_interrupt();
 }
 
 void
@@ -23,10 +29,10 @@ pwake_one(waitq_t* queue)
     }
 
     waitq_t* wq = list_entry(queue->waiters.next, waitq_t, waiters);
-    struct proc_info* proc = container_of(wq, struct proc_info, waitqueue);
+    struct thread* thread = container_of(wq, struct thread, waitqueue);
 
-    assert(proc->state == PS_BLOCKED);
-    proc->state = PS_READY;
+    assert(thread->state == PS_BLOCKED);
+    thread->state = PS_READY;
     llist_delete(&wq->waiters);
 }
 
@@ -37,13 +43,14 @@ pwake_all(waitq_t* queue)
         return;
     }
 
-    struct proc_info* proc;
+    struct thread* thread;
     waitq_t *pos, *n;
     llist_for_each(pos, n, &queue->waiters, waiters)
     {
-        proc = container_of(pos, struct proc_info, waitqueue);
+        thread = container_of(pos, struct thread, waitqueue);
 
-        proc->state = PS_READY;
+        assert(thread->state == PS_BLOCKED);
+        thread->state = PS_READY;
         llist_delete(&pos->waiters);
     }
 }
\ No newline at end of file