1 /*---------------------------------------------------------------------------*
2   Project:  Dolphin OS Thread API
3   File:     OSThread.h
4 
5   Copyright 1998-2002 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: OSThread.h,v $
14   Revision 1.3  07/22/2006 09:52:54  hirose
15   Added OSSleep* functions and macros.
16 
17   Revision 1.2  2006/02/04 11:56:48  hashida
18   (none)
19 
20   Revision 1.1.1.1  2005/12/29 06:53:28  hiratsu
21   Initial import.
22 
23   Revision 1.1.1.1  2005/05/12 02:41:07  yasuh-to
24   transitioned from the Dolphin source tree
25 
26 
27     21    8/27/02 11:46 Shiki
28     Modified OSClearStack() interface.
29 
30     20    8/19/02 21:42 Shiki
31     Added error field to OSThread{}.
32 
33     19    8/09/02 10:25 Shiki
34     Modified OSSetThreadSpecific() and OSGetThreadSpecific() interface.
35 
36     18    8/09/02 10:15:00 Shiki
37     Added OSSetThreadSpecific() and OSGetThreadSpecific().
38 
39     17     8/08/02 20:44:00 Shiki
40     Added OSSetSwitchThreadCallback().
41 
42     16     8/08/02 20:17:00 Shiki
43     Added OSClearStack().
44 
45     15    6/07/00 5:30p Tian
46     Added stack and stack size pointers into thread structure.  Changed
47     APIs for create thread and idle function.
48 
49     14    4/20/00 6:25p Shiki
50     Revised to store key data structures in lomem for debugger integration.
51 
52     13    3/07/00 10:28p Shiki
53     Changed OSCreateThread() and OSSetThreadPriority to return a BOOL
54     value.
55 
56     12    3/02/00 8:58p Shiki
57     Added OSCheckActiveThreads().
58 
59     11    2/03/00 6:19p Shiki
60     Added a new /attr/ parameter to OSCreateThread().
61 
62     10    1/28/00 3:23p Shiki
63     Revised OSJoinThread() interface.
64 
65     9     1/27/00 2:58p Shiki
66     Added more data members for implementing BPI protocol. Also changed
67     stack argument type from u32 to void*.
68 
69     7     1/25/00 6:54p Shiki
70     Added global __OSActiveThreadQueue.
71 
72     6     1/25/00 4:25p Shiki
73     Modified several definitions.
74 
75     5     1/19/00 11:31p Shiki
76     Formatted.
77 
78     4     1/18/00 4:15p Shiki
79     Implemented OSJoinThread().
80 
81     3     1/18/00 3:26p Shiki
82     Revised OSCreateThread and OSExitThread.
83 
84     2     1/18/00 10:43a Shiki
85     Implemented basic thread API.
86 
87     1     10/07/99 4:12p Shiki
88     Initial check-in.
89   $NoKeywords: $
90  *---------------------------------------------------------------------------*/
91 
92 #ifndef __OSTHREAD_H__
93 #define __OSTHREAD_H__
94 
95 #include <revolution/os/OSContext.h>
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
101 #define OS_THREAD_SPECIFIC_MAX  2
102 
103 typedef struct OSThread         OSThread;
104 typedef struct OSThreadQueue    OSThreadQueue;
105 typedef struct OSThreadLink     OSThreadLink;
106 typedef s32                     OSPriority;     //  0 highest, 31 lowest
107 
108 typedef struct OSMutex          OSMutex;
109 typedef struct OSMutexQueue     OSMutexQueue;
110 typedef struct OSMutexLink      OSMutexLink;
111 typedef struct OSCond           OSCond;
112 
113 typedef void                  (*OSIdleFunction)(void* param);
114 typedef void                  (*OSSwitchThreadCallback)(OSThread* from, OSThread* to);
115 
116 struct OSThreadQueue
117 {
118     OSThread*  head;
119     OSThread*  tail;
120 };
121 
122 struct OSThreadLink
123 {
124     OSThread*  next;
125     OSThread*  prev;
126 };
127 
128 struct OSMutexQueue
129 {
130     OSMutex*   head;
131     OSMutex*   tail;
132 };
133 
134 struct OSMutexLink
135 {
136     OSMutex*   next;
137     OSMutex*   prev;
138 };
139 
140 struct OSThread
141 {
142     OSContext       context;    // register context
143 
144     u16             state;      // OS_THREAD_STATE_*
145     u16             attr;       // OS_THREAD_ATTR_*
146     s32             suspend;    // suspended if the count is greater than zero
147     OSPriority      priority;   // effective scheduling priority
148     OSPriority      base;       // base scheduling priority
149     void*           val;        // exit value
150 
151     OSThreadQueue*  queue;      // queue thread is on
152     OSThreadLink    link;       // queue link
153 
154     OSThreadQueue   queueJoin;  // list of threads waiting for termination (join)
155 
156     OSMutex*        mutex;      // mutex trying to lock
157     OSMutexQueue    queueMutex; // list of mutexes owned
158 
159     OSThreadLink    linkActive; // link of all threads for debugging
160 
161     u8*             stackBase;  // the thread's designated stack (high address)
162     u32*            stackEnd;   // last word of stack (low address)
163 
164     s32             error;
165     void*           specific[OS_THREAD_SPECIFIC_MAX];   // thread specific data
166 };
167 
168 // Thread states
169 enum OS_THREAD_STATE
170 {
171     OS_THREAD_STATE_READY    =  1,
172     OS_THREAD_STATE_RUNNING  =  2,
173     OS_THREAD_STATE_WAITING  =  4,
174     OS_THREAD_STATE_MORIBUND =  8
175 };
176 
177 // Thread priorities
178 #define OS_PRIORITY_MIN         0                   // highest
179 #define OS_PRIORITY_MAX         31                  // lowest
180 #define OS_PRIORITY_IDLE        OS_PRIORITY_MAX
181 
182 // Thread attributes
183 #define OS_THREAD_ATTR_DETACH   0x0001u             // detached
184 
185 // Stack magic value
186 #define OS_THREAD_STACK_MAGIC   0xDEADBABE
187 
188 void       OSInitThreadQueue   ( OSThreadQueue* queue );
189 OSThread*  OSGetCurrentThread  ( void );
190 BOOL       OSIsThreadSuspended ( OSThread* thread );
191 BOOL       OSIsThreadTerminated( OSThread* thread );
192 s32        OSDisableScheduler  ( void );
193 s32        OSEnableScheduler   ( void );
194 void       OSYieldThread       ( void );
195 BOOL       OSCreateThread(       OSThread*  thread,
196                                  void*    (*func)(void*),
197                                  void*      param,
198                                  void*      stack,
199                                  u32        stackSize,
200                                  OSPriority priority,
201                                  u16        attr );
202 void       OSExitThread        ( void* val );
203 void       OSCancelThread      ( OSThread* thread );
204 BOOL       OSJoinThread        ( OSThread* thread, void** val );
205 void       OSDetachThread      ( OSThread* thread );
206 s32        OSResumeThread      ( OSThread* thread );
207 s32        OSSuspendThread     ( OSThread* thread );
208 BOOL       OSSetThreadPriority ( OSThread* thread, OSPriority priority );
209 OSPriority OSGetThreadPriority ( OSThread* thread );
210 void       OSSleepThread       ( OSThreadQueue* queue );
211 void       OSWakeupThread      ( OSThreadQueue* queue );
212 
213 // Get/Set the data specific to the calling thread
214 void*      OSGetThreadSpecific ( s32 index );
215 void       OSSetThreadSpecific ( s32 index, void* ptr );
216 
217 OSThread*  OSSetIdleFunction   ( OSIdleFunction idleFunction,
218                                  void*          param,
219                                  void*          stack,
220                                  u32            stackSize);
221 OSThread*  OSGetIdleFunction   ( void );
222 
223 void       OSClearStack        ( u8 val );
224 
225 long       OSCheckActiveThreads( void );
226 
227 OSSwitchThreadCallback OSSetSwitchThreadCallback( OSSwitchThreadCallback callback );
228 
229 
230 void       OSSleepTicks        ( OSTime ticks );
231 
232 #define OSSleepSeconds( sec )           OSSleepTicks( OSSecondsToTicks(sec) )
233 #define OSSleepMilliseconds( msec )     OSSleepTicks( OSMillisecondsToTicks(msec) )
234 #define OSSleepMicroseconds( usec )     OSSleepTicks( OSMicrosecondsToTicks(usec) )
235 #define OSSleepNanoseconds( nsec )      OSSleepTicks( OSNanosecondsToTicks(nsec) )
236 
237 
238 #ifdef __cplusplus
239 }
240 #endif
241 
242 #endif  // __OSTHREAD_H__
243