vcgencmd: Apply ASLR
[platform/adaptation/broadcom/libomxil-vc4.git] / interface / vcos / vcos_thread.h
1 /*
2 Copyright (c) 2012, Broadcom Europe Ltd
3 All rights reserved.
4
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.
15
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.
26 */
27
28 /*=============================================================================
29 VideoCore OS Abstraction Layer - public header file
30 =============================================================================*/
31
32 #ifndef VCOS_THREAD_H
33 #define VCOS_THREAD_H
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 #include "interface/vcos/vcos_types.h"
40 #include "vcos.h"
41
42 /**
43  * \file vcos_thread.h
44  *
45  * \section thread Threads
46  *
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.
50  *
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.
54  *
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.
57  *
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).
62  *
63  * \subsection stack Stack
64  *
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.
68  *
69  * \subsection thr_create Creating a thread
70  *
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
73  * vcos_thread_join().
74  *
75  * \subsection back Backward compatibility
76  *
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.
80  *
81  */
82
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
88
89 /** Report whether or not we have an RTOS at all, and hence the ability to
90   * create threads.
91   */
92 VCOSPRE_ int VCOSPOST_ vcos_have_rtos(void);
93
94 /** Create a thread. It must be cleaned up by calling vcos_thread_join().
95   *
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.
101   */
102 VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create(VCOS_THREAD_T *thread,
103                                                     const char *name,
104                                                     VCOS_THREAD_ATTR_T *attrs,
105                                                     VCOS_THREAD_ENTRY_FN_T entry,
106                                                     void *arg);
107
108 /** Exit the thread from within the thread function itself.
109   * Resources must still be cleaned up via a call to thread_join().
110   *
111   * The thread can also be terminated by simply exiting the thread function.
112   *
113   * @param data Data passed to thread_join. May be NULL.
114   */
115 VCOSPRE_ void VCOSPOST_ vcos_thread_exit(void *data);
116
117 /** Wait for a thread to terminate and then clean up its resources.
118   *
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.
122   */
123 VCOSPRE_ void VCOSPOST_ vcos_thread_join(VCOS_THREAD_T *thread,
124                              void **pData);
125
126
127 /**
128   * \brief Create a thread using an API similar to the one "traditionally"
129   * used under Nucleus.
130   *
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.
134   *
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.
145   *
146   * @sa vcos_thread_terminate vcos_thread_delete
147   */
148 VCOSPRE_ VCOS_STATUS_T VCOSPOST_ vcos_thread_create_classic(VCOS_THREAD_T *thread,
149                                                             const char *name,
150                                                             void *(*entry)(void *arg),
151                                                             void *arg,
152                                                             void *stack,
153                                                             VCOS_UNSIGNED stacksz,
154                                                             VCOS_UNSIGNED priaff,
155                                                             VCOS_UNSIGNED timeslice,
156                                                             VCOS_UNSIGNED autostart);
157
158 /**
159   * \brief Set a thread's priority
160   *
161   * Set the priority for a thread.
162   *
163   * @param thread  The thread
164   * @param pri     Thread priority in VCOS_PRI_MASK bits; affinity in VCOS_AFFINITY_MASK bits.
165   */
166 VCOS_INLINE_DECL
167 void vcos_thread_set_priority(VCOS_THREAD_T *thread, VCOS_UNSIGNED pri);
168
169 /**
170   * \brief Return the currently executing thread.
171   *
172   */
173 VCOS_INLINE_DECL
174 VCOS_THREAD_T *vcos_thread_current(void);
175
176 /**
177   * \brief Return the thread's priority.
178   */
179 VCOS_INLINE_DECL
180 VCOS_UNSIGNED vcos_thread_get_priority(VCOS_THREAD_T *thread);
181
182 /**
183   * \brief Return the thread's cpu affinity.
184   */
185 VCOS_INLINE_DECL
186 VCOS_UNSIGNED vcos_thread_get_affinity(VCOS_THREAD_T *thread);
187
188 /**
189   * \brief Set the thread's cpu affinity.
190   */
191
192 VCOS_INLINE_DECL
193 void vcos_thread_set_affinity(VCOS_THREAD_T *thread, VCOS_UNSIGNED affinity);
194
195 /**
196   * \brief Query whether we are in an interrupt.
197   *
198   * @return 1 if in interrupt context.
199   */
200 VCOS_INLINE_DECL
201 int vcos_in_interrupt(void);
202
203 /**
204   * \brief Sleep a while.
205   *
206   * @param ms Number of milliseconds to sleep for
207   *
208   * This may actually sleep a whole number of ticks.
209   */
210 VCOS_INLINE_DECL
211 void vcos_sleep(uint32_t ms);
212
213 /**
214   * \brief Return the value of the hardware microsecond counter.
215   *
216   */
217 VCOS_INLINE_DECL
218 uint32_t vcos_getmicrosecs(void);
219
220 VCOS_INLINE_DECL
221 uint64_t vcos_getmicrosecs64(void);
222
223 #define vcos_get_ms() (vcos_getmicrosecs()/1000)
224
225 /**
226   * \brief Return a unique identifier for the current process
227   *
228   */
229 VCOS_INLINE_DECL
230 VCOS_UNSIGNED vcos_process_id_current(void);
231
232 /** Relinquish this time slice. */
233 VCOS_INLINE_DECL
234 void vcos_thread_relinquish(void);
235
236 /** Return the name of the given thread.
237   */
238 VCOSPRE_ const char * VCOSPOST_ vcos_thread_get_name(const VCOS_THREAD_T *thread);
239
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).
243   *
244   * It's mainly here to ease migration. If you're using it in new code, you
245   * probably need to think again.
246   *
247   * @param pe New preemption, VCOS_PREEMPT or VCOS_NO_PREEMPT
248   * @return Old value of preemption.
249   */
250 VCOS_INLINE_DECL
251 VCOS_UNSIGNED vcos_change_preemption(VCOS_UNSIGNED pe);
252
253 /** Is a thread still running, or has it exited?
254   *
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.
257   *
258   * @param thread   thread to query
259   * @return non-zero if thread is running, or zero if it has exited.
260   */
261 VCOS_INLINE_DECL
262 int vcos_thread_running(VCOS_THREAD_T *thread);
263
264 /** Resume a thread.
265   *
266   * @param thread thread to resume
267   */
268 VCOS_INLINE_DECL
269 void vcos_thread_resume(VCOS_THREAD_T *thread);
270
271 /*
272  * Internal APIs - may not always be present and should not be used in
273  * client code.
274  */
275
276 extern void _vcos_task_timer_set(void (*pfn)(void*), void *, VCOS_UNSIGNED ms);
277 extern void _vcos_task_timer_cancel(void);
278
279 #ifdef __cplusplus
280 }
281 #endif
282 #endif