4 * [Generated from thread, 25 September 1996]
7 #if !defined(__CC_NORCROFT) || !defined(__arm)
8 #error You must use the Norcroft ARM Compiler for Sapphire programs
11 #pragma include_only_once
12 #pragma force_top_level
21 /*----- Overview ----------------------------------------------------------*
43 /* --- thread_create --- *
45 * On entry: R0 == size of stack to allocate, or 0 for a default
46 * R1 == pointer to thread routine
47 * R2 == workspace pointer to pass in R10
48 * R3 == workspace pointer to pass in R12
50 * On exit: R0 == thread handle for the thread
53 * Use: Creates a new thread running `in the background' (i.e. over
56 * The thread is passed control with the registers R10 and R12
57 * set up from R1 and R2 passed to this routine and R13 pointing
58 * to the top of a stack chunk. R0 on entry contains the
59 * thread's handle. The thread is passed the scratchpad
60 * address (in R11). The values of other registers are
61 * indeterminate and must not be relied upon.
63 * The default stack size for a new thread is 1K, although this
64 * may change in future.
66 * The thread may exit by calling thread_destroy or by
67 * returning in the normal way.
70 extern routine thread_create;
72 /* --- thread_setPriority --- *
74 * On entry: R0 == thread handle
75 * R1 == new priority to set
79 * Use: Changes the priority of a thread. The priority if a thread
80 * is a signed integer. The highest priority thread is the one
81 * which runs. If more than one thread has maximum priority,
82 * they are run in a cyclical order.
85 extern routine thread_setPriority;
87 /* --- thread_setTimeSlice --- *
89 * On entry: R0 == thread handle
90 * R1 == new timeslice size, in centiseconds
94 * Use: Changes a thread's timeslice size. Specify 0 to indicate
95 * that thread shouldn't be pre-empted.
98 extern routine thread_setTimeSlice;
100 /* --- thread_destroy --- *
102 * On entry: R0 == thread handle to destroy, if not executing a thread
106 * Use: Destroys either the current thread or a thread with the
107 * the given handle if no thread is executing currently. You
108 * can't destroy an arbitrary thread while running in one.
110 * If a thread is waiting for a semaphore, it is removed from
114 extern routine thread_destroy;
116 /* --- thread_suspend --- *
118 * On entry: R0 == thread handle, or 0 for the current thread
122 * Use: Suspends a thread's execution. If a thread is currently
123 * running, that thread is suspended. Otherwise, any thread
126 * If the thread is currently claiming semaphores, the
127 * semaphores are not released, because we don't whether the
128 * system is in a fit state for this.
130 * Thread suspensions are counted. i.e. if you suspend a thread
131 * 5 times, you have to resume it 5 times for it to become
135 extern routine thread_suspend;
137 /* --- thread_resume --- *
139 * On entry: R0 == thread handle
143 * Use: Allows a suspended thread to continue operations. If you
144 * resume a thread more times than it has been suspended,
145 * any excess resumes are ignored. You can't resume a thread
146 * to stop it being blocked by a semaphore.
149 extern routine thread_resume;
151 /* --- thread_yield --- *
157 * Use: Pauses the thread for a while. You only need to use this
158 * call if you have stopped the current thread from being
162 extern routine thread_yield;
164 /* --- thread_createSem --- *
166 * On entry: R0 == initial value for semaphore (0 for counter, 1 for
169 * On exit: R0 == semaphore handle and V clear if all went well
170 * R0 == pointer to error and V set if something went wrong
172 * Use: Creates a semaphore with the given initial counter value.
174 * The semaphore can be used to provide serialised access to
175 * a resource by initialising its value to 1 and performing the
178 * thread_wait(mySemaphore)
180 * // Do things with the resource
182 * thread_signal(mySemaphore)
184 * Or you can inform a thread that it has items in its input
185 * queue by having the following in the thread code:
188 * thread_wait(theSemaphore)
189 * getFromQueue(myQueue,item)
193 * and when inserting queue items:
196 * thread_signal(theSemaphore)
198 * It is distinctly possible that input queue management will
199 * be introduced in a separate Sapphire module.
202 extern routine thread_createSem;
204 /* --- thread_destroySem --- *
206 * On entry: R0 == semaphore handle
210 * Use: Destroys a semaphore when it's no use any more. If threads
211 * are waiting for it, an error is generated.
214 extern routine thread_destroySem;
216 /* --- thread_threaded --- *
220 * On exit: CS if currently running a thread, CC otherwise
222 * Use: Informs the caller whether a thread is currently executing.
225 extern routine thread_threaded;
227 /* --- thread_wait --- *
229 * On entry: R0 == semaphore handle
231 * On exit: If successful, R0 preserved and V clear.
232 * If failed, R0 == pointer to error block and V set
234 * Use: Waits on a sempahore. The algorithm actually is as follows:
236 * if semaphore.counter == 0 then
237 * addToWaitingList(semaphore,currentThread)
238 * suspend(currentThread)
240 * semaphore.counter -= 1
243 * See thread_createSem for suggestions on how to make use of
247 extern routine thread_wait;
249 /* --- thread_signal --- *
251 * On entry: R0 == semaphore handle
255 * Use: Increments a semaphore's counter if no threads are waiting
256 * for it, or releases a thread waiting for the semaphore.
258 * The actual algorithm is shown below:
260 * if semaphore.waitingList != 0 then
261 * thread = removeFromWaitingList(semaphore)
264 * semaphore.counter += 1;
267 * See thread_createSem for suggestions on how to make use of
271 extern routine thread_signal;
273 /* --- thread_init --- *
279 * Use: Initialises the thread system for use.
282 extern routine thread_init;
284 /* --- thread_enterCrit --- *
290 * Use: Declares that the current thread is about to enter a
291 * critical section and must not be interrupted.
294 extern routine thread_enterCrit;
296 /* --- thread_leaveCrit --- *
302 * Use: Declares that the current thread has left the critical
303 * section and can be interrupted again.
306 extern routine thread_leaveCrit;
308 /* --- thread_errorHandler --- *
310 * On entry: R0 == pointer to routine to call
311 * R1 == R12 value to call with
312 * R2 == R13 value to call with
316 * Use: Sets up the error handler for a thread.
319 extern routine thread_errorHandler;
321 /*----- That's all, folks -------------------------------------------------*/