Modules/Tegra2Vid - Got it compiling
[tpg/acess2.git] / 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 // === CODE ===
13 void Workqueue_Init(tWorkqueue *Queue, const char *Name, size_t NextOfset)
14 {
15         Queue->Name = Name;
16         Queue->NextOffset = NextOfset;
17 }
18
19 void *Workqueue_GetWork(tWorkqueue *Queue)
20 {
21         tThread *us;
22
23         for( ;; )
24         {
25                 // Check for work
26                 SHORTLOCK(&Queue->Protector);
27                 if(Queue->Head)
28                 {
29                         void *ret = Queue->Head;
30                         Queue->Head = *( (void**)ret + Queue->NextOffset/sizeof(void*) );
31                         if(Queue->Tail == ret)
32                                 Queue->Tail = NULL;
33                         SHORTREL(&Queue->Protector);    
34                         return ret;
35                 }
36                 
37                 // Go to sleep
38                 SHORTLOCK(&glThreadListLock);
39                 us = Threads_RemActive();
40                 us->WaitPointer = Queue;
41                 us->Status = THREAD_STAT_QUEUESLEEP;
42                 Queue->Sleeper = us;
43                 SHORTREL(&Queue->Protector);    
44                 SHORTREL(&glThreadListLock);
45                 
46                 // Yield and sleep
47                 Threads_Yield();
48                 if(us->Status == THREAD_STAT_QUEUESLEEP) {
49                         // Why are we awake?!
50                 }
51
52                 us->WaitPointer = NULL;
53         }
54 }
55
56 void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
57 {
58         SHORTLOCK(&Queue->Protector);
59
60         if( Queue->Tail )
61                 *( (void**)Queue->Tail + Queue->NextOffset/sizeof(void*) ) = Ptr;
62         else
63                 Queue->Head = Ptr;
64         Queue->Tail = Ptr;
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