Kernel/timers - Cleaning up timer code... might have made more mess
[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_Yield();
50                 if(us->Status == THREAD_STAT_QUEUESLEEP) {
51                         // Why are we awake?!
52                 }
53
54                 us->WaitPointer = NULL;
55         }
56 }
57
58 void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
59 {
60         SHORTLOCK(&Queue->Protector);
61
62         if( Queue->Tail )
63                 QUEUENEXT(Queue->Tail) = Ptr;
64         else
65                 Queue->Head = Ptr;
66         Queue->Tail = Ptr;
67         QUEUENEXT(Ptr) = NULL;
68
69         if( Queue->Sleeper )
70         {       
71                 if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
72                         Threads_AddActive(Queue->Sleeper);
73                 Queue->Sleeper = NULL;
74         }
75         SHORTREL(&Queue->Protector);
76 }

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