Usermode/libc - Fix strchr and strrchr behavior
[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         Queue->Sleeper = NULL;
20         Queue->SleepTail = NULL;
21 }
22
23 void *Workqueue_GetWork(tWorkqueue *Queue)
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                 Threads_int_Sleep(THREAD_STAT_QUEUESLEEP,
40                         Queue, 0,
41                         &Queue->Sleeper, &Queue->SleepTail, &Queue->Protector);
42         }
43 }
44
45 void Workqueue_AddWork(tWorkqueue *Queue, void *Ptr)
46 {
47         SHORTLOCK(&Queue->Protector);
48
49         if( Queue->Tail )
50                 QUEUENEXT(Queue->Tail) = Ptr;
51         else
52                 Queue->Head = Ptr;
53         Queue->Tail = Ptr;
54         QUEUENEXT(Ptr) = NULL;
55
56         if( Queue->Sleeper )
57         {       
58                 ASSERTC( Queue->Sleeper->Status, !=, THREAD_STAT_ACTIVE );
59                 tThread *next_sleeper = Queue->Sleeper->Next;
60                 Threads_AddActive(Queue->Sleeper);
61                 Queue->Sleeper = next_sleeper;
62                 if(!next_sleeper)
63                         Queue->SleepTail = NULL;
64         }
65         SHORTREL(&Queue->Protector);
66 }

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