Kernel - Updated events and workqueue to use new function
[tpg/acess2.git] / KernelLand / Kernel / workqueue.c
1 /*
2  * Acess2 Kernel
3  * - By John Hodge (thePowersGang)
4  *
5  * workqueue.c
6  * - Worker FIFO Queue (Single Consumer, Interrupt Producer)
7  */
8 #include <acess.h>
9 #include <workqueue.h>
10 #include <threads_int.h>
11
12 #define QUEUENEXT(ptr)  (*( (void**)(ptr) + Queue->NextOffset/sizeof(void*) ))
13
14 // === CODE ===
15 void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset)
16 {
17         Queue->Name = Name;
18         Queue->NextOffset = NextOfset;
19 }
20
21 void *Workqueue_GetWork(tWorkqueue *Queue)
22 {
23         tThread *us;
24
25         for( ;; )
26         {
27                 // Check for work
28                 SHORTLOCK(&Queue->Protector);
29                 if(Queue->Head)
30                 {
31                         void *ret = Queue->Head;
32                         Queue->Head = QUEUENEXT( ret );
33                         if(Queue->Tail == ret)
34                                 Queue->Tail = NULL;
35                         SHORTREL(&Queue->Protector);    
36                         return ret;
37                 }
38                 
39                 // Go to sleep
40                 SHORTLOCK(&glThreadListLock);
41                 us = Threads_RemActive();
42                 us->WaitPointer = Queue;
43                 us->Status = THREAD_STAT_QUEUESLEEP;
44                 Queue->Sleeper = us;
45                 SHORTREL(&Queue->Protector);    
46                 SHORTREL(&glThreadListLock);
47                 
48                 // Yield and sleep
49                 Threads_int_WaitForStatusEnd(THREAD_STAT_QUEUESLEEP);
50
51                 us->WaitPointer = NULL;
52         }
53 }
54
55 void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
56 {
57         SHORTLOCK(&Queue->Protector);
58
59         if( Queue->Tail )
60                 QUEUENEXT(Queue->Tail) = Ptr;
61         else
62                 Queue->Head = Ptr;
63         Queue->Tail = Ptr;
64         QUEUENEXT(Ptr) = NULL;
65
66         if( Queue->Sleeper )
67         {       
68                 if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
69                         Threads_AddActive(Queue->Sleeper);
70                 Queue->Sleeper = NULL;
71         }
72         SHORTREL(&Queue->Protector);
73 }

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