Kernel/VTerm - "Fix" wrapping issue in VTerm (why was old behavior there?)
[tpg/acess2.git] / KernelLand / Kernel / workqueue.c
index b1a6385..f5d78f8 100644 (file)
@@ -9,17 +9,19 @@
 #include <workqueue.h>
 #include <threads_int.h>
 
+#define QUEUENEXT(ptr) (*( (void**)(ptr) + Queue->NextOffset/sizeof(void*) ))
+
 // === CODE ===
 void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset)
 {
        Queue->Name = Name;
        Queue->NextOffset = NextOfset;
+       Queue->Sleeper = NULL;
+       Queue->SleepTail = NULL;
 }
 
 void *Workqueue_GetWork(tWorkqueue *Queue)
 {
-       tThread *us;
-
        for( ;; )
        {
                // Check for work
@@ -27,29 +29,16 @@ void *Workqueue_GetWork(tWorkqueue *Queue)
                if(Queue->Head)
                {
                        void *ret = Queue->Head;
-                       Queue->Head = *( (void**)ret + Queue->NextOffset/sizeof(void*) );
+                       Queue->Head = QUEUENEXT( ret );
                        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;
+               Threads_int_Sleep(THREAD_STAT_QUEUESLEEP,
+                       Queue, 0,
+                       &Queue->Sleeper, &Queue->SleepTail, &Queue->Protector);
        }
 }
 
@@ -58,16 +47,20 @@ void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
        SHORTLOCK(&Queue->Protector);
 
        if( Queue->Tail )
-               *( (void**)Queue->Tail + Queue->NextOffset/sizeof(void*) ) = Ptr;
+               QUEUENEXT(Queue->Tail) = Ptr;
        else
                Queue->Head = Ptr;
        Queue->Tail = Ptr;
-       
+       QUEUENEXT(Ptr) = NULL;
+
        if( Queue->Sleeper )
        {       
-               if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
-                       Threads_AddActive(Queue->Sleeper);
-               Queue->Sleeper = NULL;
+               ASSERTC( Queue->Sleeper->Status, !=, THREAD_STAT_ACTIVE );
+               tThread *next_sleeper = Queue->Sleeper->Next;
+               Threads_AddActive(Queue->Sleeper);
+               Queue->Sleeper = next_sleeper;
+               if(!next_sleeper)
+                       Queue->SleepTail = NULL;
        }
        SHORTREL(&Queue->Protector);
 }

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