Kernel - Added a FIFO to thread code
authorJohn Hodge <[email protected]>
Tue, 29 Nov 2011 15:18:41 +0000 (23:18 +0800)
committerJohn Hodge <[email protected]>
Tue, 29 Nov 2011 15:18:41 +0000 (23:18 +0800)
Kernel/include/threads_int.h
Kernel/include/workqueue.h [new file with mode: 0644]
Kernel/workqueue.c [new file with mode: 0644]

index 4cc11ec..6516b35 100644 (file)
@@ -78,6 +78,7 @@ enum {
        THREAD_STAT_SLEEPING,   // Message Sleep
        THREAD_STAT_MUTEXSLEEP, // Mutex Sleep
        THREAD_STAT_SEMAPHORESLEEP,     // Semaphore Sleep
+       THREAD_STAT_QUEUESLEEP, // Queue
        THREAD_STAT_WAITING,    // ??? (Waiting for a thread)
        THREAD_STAT_PREINIT,    // Being created
        THREAD_STAT_ZOMBIE,     // Died/Killed, but parent not informed
@@ -90,6 +91,7 @@ static const char * const casTHREAD_STAT[] = {
        "THREAD_STAT_SLEEPING",
        "THREAD_STAT_MUTEXSLEEP",
        "THREAD_STAT_SEMAPHORESLEEP",
+       "THREAD_STAT_QUEUESLEEP",
        "THREAD_STAT_WAITING",
        "THREAD_STAT_PREINIT",
        "THREAD_STAT_ZOMBIE",
diff --git a/Kernel/include/workqueue.h b/Kernel/include/workqueue.h
new file mode 100644 (file)
index 0000000..ff0c7f4
--- /dev/null
@@ -0,0 +1,31 @@
+/**
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * workqueue.h
+ * - FIFO Queue
+ */
+#ifndef _WORKQUEUE_H_
+#define _WORKQUEUE_H_
+
+#include <acess.h>
+
+typedef struct sWorkqueue      tWorkqueue;
+
+struct sWorkqueue
+{
+       tShortSpinlock  Protector;
+       const char      *Name;
+        int    NextOffset;
+       
+       void    *Head;
+       void    *Tail;
+       struct sThread  *Sleeper;
+};
+
+extern void    Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset);
+extern void    *Workqueue_GetWork(tWorkqueue *Queue);
+extern void    Workqueue_AddWork(tWorkqueue *Queue, void *Ptr);
+
+#endif
+
diff --git a/Kernel/workqueue.c b/Kernel/workqueue.c
new file mode 100644 (file)
index 0000000..38bf932
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * workqueue.c
+ * - Worker FIFO Queue (Single Consumer, Interrupt Producer)
+ */
+#include <acess.h>
+#include <workqueue.h>
+#include <threads_int.h>
+
+// === CODE ===
+void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset)
+{
+       Queue->Name = Name;
+       Queue->NextOffset = NextOfset;
+}
+
+void *Workqueue_GetWork(tWorkqueue *Queue)
+{
+       tThread *us;
+
+       for( ;; )
+       {
+               // Check for work
+               SHORTLOCK(&Queue->Protector);
+               if(Queue->Head)
+               {
+                       void *ret = Queue->Head;
+                       Queue->Head = *(void**)( (char*)ret + Queue->NextOffset );
+                       if(Queue->Tail == ret)
+                               Queue->Tail = NULL;
+                       SHORTREL(&Queue->Protector);    
+                       return ret;
+               }
+               
+               // Go to sleep
+               SHORTLOCK(&glThreadListLock);
+               us = Threads_RemActive();
+               us->WaitPointer = Queue;
+               us->Status = THREAD_STAT_QUEUESLEEP;
+               Queue->Sleeper = us;
+               SHORTREL(&Queue->Protector);    
+               SHORTREL(&glThreadListLock);
+               
+               // Yield and sleep
+               Threads_Yield();
+               if(us->Status == THREAD_STAT_QUEUESLEEP) {
+                       // Why are we awake?!
+               }
+
+               us->WaitPointer = NULL;
+       }
+}
+
+void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
+{
+       SHORTLOCK(&Queue->Protector);
+
+       if( Queue->Tail )
+               *(void**)( (char*)Queue->Tail + Queue->NextOffset ) = Ptr;
+       else
+               Queue->Head = Ptr;
+       Queue->Tail = Ptr;
+       
+       if( Queue->Sleeper )
+       {       
+               SHORTLOCK( &glThreadListLock );
+               if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
+                       Threads_AddActive(Queue->Sleeper);
+               SHORTREL( &glThreadListLock );
+               Queue->Sleeper = NULL;
+       }
+       SHORTREL(&Queue->Protector);
+}

UCC git Repository :: git.ucc.asn.au