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