Kernel - Converted most blocking states to use Threads_int_Sleep
[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         for( ;; )
24         {
25                 // Check for work
26                 SHORTLOCK(&Queue->Protector);
27                 if(Queue->Head)
28                 {
29                         void *ret = Queue->Head;
30                         Queue->Head = QUEUENEXT( ret );
31                         if(Queue->Tail == ret)
32                                 Queue->Tail = NULL;
33                         SHORTREL(&Queue->Protector);    
34                         return ret;
35                 }
36                 
37                 Threads_int_Sleep(THREAD_STAT_QUEUESLEEP,
38                         Queue, 0,
39                         &Queue->Sleeper, NULL, &Queue->Protector);
40         }
41 }
42
43 void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
44 {
45         SHORTLOCK(&Queue->Protector);
46
47         if( Queue->Tail )
48                 QUEUENEXT(Queue->Tail) = Ptr;
49         else
50                 Queue->Head = Ptr;
51         Queue->Tail = Ptr;
52         QUEUENEXT(Ptr) = NULL;
53
54         if( Queue->Sleeper )
55         {       
56                 if( Queue->Sleeper->Status != THREAD_STAT_ACTIVE )
57                         Threads_AddActive(Queue->Sleeper);
58                 Queue->Sleeper = NULL;
59         }
60         SHORTREL(&Queue->Protector);
61 }

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