root / Whitix / branches / hybrid / include / wait.h

Revision 349, 2.5 kB (checked in by mwhitworth, 6 months ago)

Add ListAdd instead of ListAddTail.

Line 
1/*  This file is part of Whitix.
2 *
3 *  Whitix is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  Whitix is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with Whitix; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#ifndef WAIT_H
20#define WAIT_H
21
22#include <llist.h>
23#include <sched.h>
24#include <typedefs.h>
25
26/* Uncomment this if you'd like to investigate strange wait-queue behaviour. */
27/* #define WAIT_DEBUG */
28
29struct WaitQueueTag
30{
31        struct ListHead list;
32        Spinlock spinLock;
33};
34
35typedef struct WaitQueueTag WaitQueue;
36
37#define DECLARE_WAITQUEUE_HEAD(waitQueue) \
38        WaitQueue waitQueue={LIST_HEAD_INIT((waitQueue).list),{0}}
39
40#define INIT_WAITQUEUE_HEAD(waitQueue) \
41        do { INIT_LIST_HEAD(&((waitQueue)->list)); (waitQueue)->spinLock.flags=0; } while (0)
42
43struct WaitQueueEntry
44{
45        struct Thread* thread;
46        struct ListHead next;
47
48#ifdef WAIT_DEBUG
49        unsigned int magic;
50#endif
51
52};
53
54static inline void WaitAddToQueue(WaitQueue* waitQueue,struct WaitQueueEntry* waitEntry)
55{
56        SpinLockIrq(&waitQueue->spinLock);
57
58#ifdef WAIT_DEBUG
59        waitEntry->magic = 0xDEADBEEF;
60#endif
61
62        ListAdd(&waitEntry->next,&waitQueue->list);
63        SpinUnlockIrq(&waitQueue->spinLock);
64}
65
66static inline void WaitRemoveFromQueue(WaitQueue* waitQueue,struct WaitQueueEntry* waitEntry)
67{
68        SpinLockIrq(&waitQueue->spinLock);
69
70        ListRemove(&waitEntry->next);
71
72#ifdef WAIT_DEBUG
73        if (waitEntry->magic != 0xDEADBEEF) printf("Remove error!, %#X\n",waitEntry->magic);
74#endif
75
76
77        SpinUnlockIrq(&waitQueue->spinLock);
78}
79
80#define WAIT_ON(waitQueue,condition) \
81do{ \
82        if ((condition)) \
83                break; \
84        struct WaitQueueEntry waitEntry={currThread,{NULL,NULL}}; \
85        ThrGetThread(currThread); \
86        while (1) { \
87                if ((condition)) break; \
88                WaitAddToQueue(&(waitQueue),&waitEntry); \
89                ThrSuspendThread(currThread); \
90                ThrSchedule(); /* Will return here when the thread is scheduled again */ \
91                WaitRemoveFromQueue(&(waitQueue),&waitEntry); \
92        } \
93        ThrReleaseThread(currThread); \
94}while(0)
95
96void WakeUp(WaitQueue* waitQueue);
97
98#endif
Note: See TracBrowser for help on using the browser.