2 Copyright (c) 2012, Broadcom Europe Ltd
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 /*=============================================================================
29 VideoCore OS Abstraction Layer - public header file
30 =============================================================================*/
39 #include "interface/vcos/vcos_types.h"
45 * \section thread Threads
47 * Under Nucleus, a thread is created by NU_Create_Task, passing in the stack
48 * and various other parameters. To stop the thread, NU_Terminate_Thread() and
49 * NU_Delete_Thread() are called.
51 * Unfortunately it's not possible to emulate this API under some fairly common
52 * operating systems. Under Windows you can't pass in the stack, and you can't
53 * safely terminate a thread.
55 * Therefore, an API which is similar to the pthreads API is used instead. This
56 * API can (mostly) be emulated under all interesting operating systems.
58 * Obviously this makes the code somewhat more complicated on VideoCore than it
59 * would otherwise be - we end up with an extra mutex per thread, and some code
60 * that waits for it. The benefit is that we have a single way of creating
61 * threads that works consistently on all platforms (apart from stack supplying).
63 * \subsection stack Stack
65 * It's still not possible to pass in the stack address, but this can be made
66 * much more obvious in the API: the relevant function is missing and the
67 * CPP symbol VCOS_CAN_SET_STACK_ADDR is zero rather than one.
69 * \subsection thr_create Creating a thread
71 * The simplest way to create a thread is with vcos_thread_create() passing in a
72 * NULL thread parameter argument. To wait for the thread to exit, call
75 * \subsection back Backward compatibility
77 * To ease migration, a "classic" thread creation API is provided for code
78 * that used to make use of Nucleus, vcos_thread_create_classic(). The
79 * arguments are not exactly the same, as the PREEMPT parameter is dropped.
83 #define VCOS_AFFINITY_CPU0 _VCOS_AFFINITY_CPU0
84 #define VCOS_AFFINITY_CPU1 _VCOS_AFFINITY_CPU1
85 #define VCOS_AFFINITY_MASK _VCOS_AFFINITY_MASK
86 #define VCOS_AFFINITY_DEFAULT _VCOS_AFFINITY_DEFAULT
87 #define VCOS_AFFINITY_THISCPU _VCOS_AFFINITY_THISCPU
89 /** Report whether or not we have an RTOS at all, and hence the ability to
92 VCOSPRE_ int VCOSPOST_ vcos_have_rtos(void);
94 /** Create a thread. It must be cleaned up by calling vcos_thread_join().
96 * @param thread Filled in on return with thread
97 * @param name A name for the thread. May be the empty string.
98 * @param attrs Attributes; default attributes will be used if this is NULL.
99 * @param entry Entry point.
100 * @param arg Argument passed to the entry point.
102 VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create(VCOS_THREAD_T *thread,
104 VCOS_THREAD_ATTR_T *attrs,
105 VCOS_THREAD_ENTRY_FN_T entry,
108 /** Exit the thread from within the thread function itself.
109 * Resources must still be cleaned up via a call to thread_join().
111 * The thread can also be terminated by simply exiting the thread function.
113 * @param data Data passed to thread_join. May be NULL.
115 VCOSPRE_ void VCOSPOST_ vcos_thread_exit(void *data);
117 /** Wait for a thread to terminate and then clean up its resources.
119 * @param thread Thread to wait for
120 * @param pData Updated to point at data provided in vcos_thread_exit or exit
121 * code of thread function.
123 VCOSPRE_ void VCOSPOST_ vcos_thread_join(VCOS_THREAD_T *thread,
128 * \brief Create a thread using an API similar to the one "traditionally"
129 * used under Nucleus.
131 * This creates a thread which must be cleaned up by calling vcos_thread_join().
132 * The thread cannot be simply terminated (as in Nucleus and ThreadX) as thread
133 * termination is not universally supported.
135 * @param thread Filled in with thread instance
136 * @param name An optional name for the thread. NULL or "" may be used (but
137 * a name will aid in debugging).
138 * @param entry Entry point
139 * @param arg A single argument passed to the entry point function
140 * @param stack Pointer to stack address
141 * @param stacksz Size of stack in bytes
142 * @param priaff Priority of task, between VCOS_PRI_LOW and VCOS_PRI_HIGH, ORed with the CPU affinity
143 * @param autostart If non-zero the thread will start immediately.
144 * @param timeslice Timeslice (system ticks) for this thread.
146 * @sa vcos_thread_terminate vcos_thread_delete
148 VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
150 void *(*entry)(void *arg),
153 VCOS_UNSIGNED stacksz,
154 VCOS_UNSIGNED priaff,
155 VCOS_UNSIGNED timeslice,
156 VCOS_UNSIGNED autostart);
159 * \brief Set a thread's priority
161 * Set the priority for a thread.
163 * @param thread The thread
164 * @param pri Thread priority in VCOS_PRI_MASK bits; affinity in VCOS_AFFINITY_MASK bits.
167 void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED pri);
170 * \brief Return the currently executing thread.
174 VCOS_THREAD_T *vcos_thread_current(void);
177 * \brief Return the thread's priority.
180 VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread);
183 * \brief Return the thread's cpu affinity.
186 VCOS_UNSIGNED vcos_thread_get_affinity(VCOS_THREAD_T *thread);
189 * \brief Set the thread's cpu affinity.
193 void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity);
196 * \brief Query whether we are in an interrupt.
198 * @return 1 if in interrupt context.
201 int vcos_in_interrupt(void);
204 * \brief Sleep a while.
206 * @param ms Number of milliseconds to sleep for
208 * This may actually sleep a whole number of ticks.
211 void vcos_sleep(uint32_t ms);
214 * \brief Return the value of the hardware microsecond counter.
218 uint32_t vcos_getmicrosecs(void);
221 uint64_t vcos_getmicrosecs64(void);
223 #define vcos_get_ms() (vcos_getmicrosecs()/1000)
226 * \brief Return a unique identifier for the current process
230 VCOS_UNSIGNED vcos_process_id_current(void);
232 /** Relinquish this time slice. */
234 void vcos_thread_relinquish(void);
236 /** Return the name of the given thread.
238 VCOSPRE_ const char * VCOSPOST_ vcos_thread_get_name(const VCOS_THREAD_T *thread);
240 /** Change preemption. This is almost certainly not what you want, as it won't
241 * work reliably in a multicore system: although you can affect the preemption
242 * on *this* core, you won't affect what's happening on the other core(s).
244 * It's mainly here to ease migration. If you're using it in new code, you
245 * probably need to think again.
247 * @param pe New preemption, VCOS_PREEMPT or VCOS_NO_PREEMPT
248 * @return Old value of preemption.
251 VCOS_UNSIGNED vcos_change_preemption(VCOS_UNSIGNED pe);
253 /** Is a thread still running, or has it exited?
255 * Note: this exists for some fairly scary code in the video codec tests. Don't
256 * try to use it for anything else, as it may well not do what you expect.
258 * @param thread thread to query
259 * @return non-zero if thread is running, or zero if it has exited.
262 int vcos_thread_running(VCOS_THREAD_T *thread);
266 * @param thread thread to resume
269 void vcos_thread_resume(VCOS_THREAD_T *thread);
272 * Internal APIs - may not always be present and should not be used in
276 extern void _vcos_task_timer_set(void (*pfn)(void*), void *, VCOS_UNSIGNED ms);
277 extern void _vcos_task_timer_cancel(void);