| 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 - basic types |
| 30 | =============================================================================*/ |
| 31 | |
| 32 | #ifndef VCOS_TYPES_H |
| 33 | #define VCOS_TYPES_H |
| 34 | |
| 35 | #define VCOS_VERSION 1 |
| 36 | |
| 37 | #include <stddef.h> |
| 38 | #if defined(__unix__) && !defined(__ANDROID__) |
| 39 | #include "interface/vcos/pthreads/vcos_platform_types.h" |
| 40 | #else |
| 41 | #include "vcos_platform_types.h" |
| 42 | #endif |
| 43 | #include "interface/vcos/vcos_attr.h" |
| 44 | |
| 45 | #if !defined(VCOSPRE_) || !defined(VCOSPOST_) |
| 46 | #error VCOSPRE_ or VCOSPOST_ not defined! |
| 47 | #endif |
| 48 | |
| 49 | /* Redefine these here; this means that existing header files can carry on |
| 50 | * using the VCHPOST/VCHPRE macros rather than having huge changes, which |
| 51 | * could cause nasty merge problems. |
| 52 | */ |
| 53 | #ifndef VCHPOST_ |
| 54 | #define VCHPOST_ VCOSPOST_ |
| 55 | #endif |
| 56 | #ifndef VCHPRE_ |
| 57 | #define VCHPRE_ VCOSPRE_ |
| 58 | #endif |
| 59 | |
| 60 | /** Entry function for a lowlevel thread. |
| 61 | * |
| 62 | * Returns void for consistency with Nucleus/ThreadX. |
| 63 | */ |
| 64 | typedef void (*VCOS_LLTHREAD_ENTRY_FN_T)(void *); |
| 65 | |
| 66 | /** Thread entry point. Returns a void* for consistency |
| 67 | * with pthreads. |
| 68 | */ |
| 69 | typedef void *(*VCOS_THREAD_ENTRY_FN_T)(void*); |
| 70 | |
| 71 | |
| 72 | /* Error return codes - chosen to be similar to errno values */ |
| 73 | typedef enum |
| 74 | { |
| 75 | VCOS_SUCCESS, |
| 76 | VCOS_EAGAIN, |
| 77 | VCOS_ENOENT, |
| 78 | VCOS_ENOSPC, |
| 79 | VCOS_EINVAL, |
| 80 | VCOS_EACCESS, |
| 81 | VCOS_ENOMEM, |
| 82 | VCOS_ENOSYS, |
| 83 | VCOS_EEXIST, |
| 84 | VCOS_ENXIO, |
| 85 | VCOS_EINTR |
| 86 | } VCOS_STATUS_T; |
| 87 | |
| 88 | /* Some compilers (MetaWare) won't inline with -g turned on, which then results |
| 89 | * in a lot of code bloat. To overcome this, inline functions are forward declared |
| 90 | * with the prefix VCOS_INLINE_DECL, and implemented with the prefix VCOS_INLINE_IMPL. |
| 91 | * |
| 92 | * That then means that in a release build, "static inline" can be used in the obvious |
| 93 | * way, but in a debug build the implementations can be skipped in all but one file, |
| 94 | * by using VCOS_INLINE_BODIES. |
| 95 | * |
| 96 | * VCOS_INLINE_DECL - put this at the start of an inline forward declaration of a VCOS |
| 97 | * function. |
| 98 | * |
| 99 | * VCOS_INLINE_IMPL - put this at the start of an inlined implementation of a VCOS |
| 100 | * function. |
| 101 | * |
| 102 | */ |
| 103 | |
| 104 | /* VCOS_EXPORT - it turns out that in some circumstances we need the implementation of |
| 105 | * a function even if it is usually inlined. |
| 106 | * |
| 107 | * In particular, if we have a codec that is usually provided in object form, if it |
| 108 | * was built for a debug build it will be full of calls to vcos_XXX(). If this is used |
| 109 | * in a *release* build, then there won't be any of these calls around in the main image |
| 110 | * as they will all have been inlined. The problem also exists for vcos functions called |
| 111 | * from assembler. |
| 112 | * |
| 113 | * VCOS_EXPORT ensures that the named function will be emitted as a regular (not static-inline) |
| 114 | * function inside vcos_<platform>.c so that it can be linked against. Doing this for every |
| 115 | * VCOS function would be a bit code-bloat-tastic, so it is only done for those that need it. |
| 116 | * |
| 117 | */ |
| 118 | |
| 119 | #ifdef __cplusplus |
| 120 | #define _VCOS_INLINE inline |
| 121 | #else |
| 122 | #define _VCOS_INLINE __inline |
| 123 | #endif |
| 124 | |
| 125 | #if defined(NDEBUG) |
| 126 | |
| 127 | #ifdef __GNUC__ |
| 128 | # define VCOS_INLINE_DECL extern __inline__ |
| 129 | # define VCOS_INLINE_IMPL static __inline__ |
| 130 | #else |
| 131 | # define VCOS_INLINE_DECL static _VCOS_INLINE /* declare a func */ |
| 132 | # define VCOS_INLINE_IMPL static _VCOS_INLINE /* implement a func inline */ |
| 133 | #endif |
| 134 | |
| 135 | # if defined(VCOS_WANT_IMPL) |
| 136 | # define VCOS_EXPORT |
| 137 | # else |
| 138 | # define VCOS_EXPORT VCOS_INLINE_IMPL |
| 139 | # endif /* VCOS_WANT_IMPL */ |
| 140 | |
| 141 | #define VCOS_INLINE_BODIES |
| 142 | |
| 143 | #else /* NDEBUG */ |
| 144 | |
| 145 | #if !defined(VCOS_INLINE_DECL) |
| 146 | #define VCOS_INLINE_DECL extern |
| 147 | #endif |
| 148 | #if !defined(VCOS_INLINE_IMPL) |
| 149 | #define VCOS_INLINE_IMPL |
| 150 | #endif |
| 151 | #define VCOS_EXPORT VCOS_INLINE_IMPL |
| 152 | #endif |
| 153 | |
| 154 | #define VCOS_STATIC_INLINE static _VCOS_INLINE |
| 155 | |
| 156 | #if defined(__HIGHC__) || defined(__HIGHC_ANSI__) |
| 157 | #define _VCOS_METAWARE |
| 158 | #endif |
| 159 | |
| 160 | /** It seems that __FUNCTION__ isn't standard! |
| 161 | */ |
| 162 | #if __STDC_VERSION__ < 199901L |
| 163 | # if __GNUC__ >= 2 || defined(__VIDEOCORE__) |
| 164 | # define VCOS_FUNCTION __FUNCTION__ |
| 165 | # else |
| 166 | # define VCOS_FUNCTION "<unknown>" |
| 167 | # endif |
| 168 | #else |
| 169 | # define VCOS_FUNCTION __func__ |
| 170 | #endif |
| 171 | |
| 172 | #define _VCOS_MS_PER_TICK (1000/VCOS_TICKS_PER_SECOND) |
| 173 | |
| 174 | /* Convert a number of milliseconds to a tick count. Internal use only - fails to |
| 175 | * convert VCOS_SUSPEND correctly. |
| 176 | */ |
| 177 | #define _VCOS_MS_TO_TICKS(ms) (((ms)+_VCOS_MS_PER_TICK-1)/_VCOS_MS_PER_TICK) |
| 178 | |
| 179 | #define VCOS_TICKS_TO_MS(ticks) ((ticks) * _VCOS_MS_PER_TICK) |
| 180 | |
| 181 | /** VCOS version of DATESTR, from pcdisk.h. Used by the hostreq service. |
| 182 | */ |
| 183 | typedef struct vcos_datestr |
| 184 | { |
| 185 | uint8_t cmsec; /**< Centesimal mili second */ |
| 186 | uint16_t date; /**< Date */ |
| 187 | uint16_t time; /**< Time */ |
| 188 | |
| 189 | } VCOS_DATESTR; |
| 190 | |
| 191 | /* Compile-time assert - declares invalid array length if condition |
| 192 | * not met, or array of length one if OK. |
| 193 | */ |
| 194 | #define VCOS_CASSERT(e) extern char vcos_compile_time_check[1/(e)] |
| 195 | |
| 196 | #define vcos_min(x,y) ((x) < (y) ? (x) : (y)) |
| 197 | #define vcos_max(x,y) ((x) > (y) ? (x) : (y)) |
| 198 | |
| 199 | /** Return the count of an array. FIXME: under gcc we could make |
| 200 | * this report an error for pointers using __builtin_types_compatible(). |
| 201 | */ |
| 202 | #define vcos_countof(x) (sizeof((x)) / sizeof((x)[0])) |
| 203 | |
| 204 | /* for backward compatibility */ |
| 205 | #define countof(x) (sizeof((x)) / sizeof((x)[0])) |
| 206 | |
| 207 | #define VCOS_ALIGN_DOWN(p,n) (((ptrdiff_t)(p)) & ~((n)-1)) |
| 208 | #define VCOS_ALIGN_UP(p,n) VCOS_ALIGN_DOWN((ptrdiff_t)(p)+(n)-1,(n)) |
| 209 | |
| 210 | #ifdef _MSC_VER |
| 211 | #define vcos_alignof(T) __alignof(T) |
| 212 | #elif defined(__GNUC__) |
| 213 | #define vcos_alignof(T) __alignof__(T) |
| 214 | #else |
| 215 | #define vcos_alignof(T) (sizeof(struct { T t; char ch; }) - sizeof(T)) |
| 216 | #endif |
| 217 | |
| 218 | /** bool_t is not a POSIX type so cannot rely on it. Define it here. |
| 219 | * It's not even defined in stdbool.h. |
| 220 | */ |
| 221 | typedef int32_t vcos_bool_t; |
| 222 | typedef int32_t vcos_fourcc_t; |
| 223 | |
| 224 | #define VCOS_FALSE 0 |
| 225 | #define VCOS_TRUE (!VCOS_FALSE) |
| 226 | |
| 227 | /** Mark unused arguments to keep compilers quiet */ |
| 228 | #define vcos_unused(x) (void)(x) |
| 229 | |
| 230 | /** For backward compatibility */ |
| 231 | typedef vcos_fourcc_t fourcc_t; |
| 232 | typedef vcos_fourcc_t FOURCC_T; |
| 233 | |
| 234 | #ifdef __cplusplus |
| 235 | #define VCOS_EXTERN_C_BEGIN extern "C" { |
| 236 | #define VCOS_EXTERN_C_END } |
| 237 | #else |
| 238 | #define VCOS_EXTERN_C_BEGIN |
| 239 | #define VCOS_EXTERN_C_END |
| 240 | #endif |
| 241 | |
| 242 | /** Define a function as a weak alias to another function. |
| 243 | * @param ret_type Function return type. |
| 244 | * @param alias_name Name of the alias. |
| 245 | * @param param_list Function parameter list, including the parentheses. |
| 246 | * @param target_name Target function (bare function name, not a string). |
| 247 | */ |
| 248 | #if defined(__GNUC__) || defined(_VCOS_METAWARE) |
| 249 | /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ |
| 250 | # define VCOS_WEAK_ALIAS(ret_type, alias_name, param_list, target_name) \ |
| 251 | __attribute__ ((weak, alias(#target_name))) ret_type alias_name param_list |
| 252 | #else |
| 253 | # define VCOS_WEAK_ALIAS(ret_type, alias, params, target) VCOS_CASSERT(0) |
| 254 | #endif |
| 255 | |
| 256 | /** Define a function as a weak alias to another function, specified as a string. |
| 257 | * @param ret_type Function return type. |
| 258 | * @param alias_name Name of the alias. |
| 259 | * @param param_list Function parameter list, including the parentheses. |
| 260 | * @param target_name Target function name as a string. |
| 261 | * @note Prefer the use of VCOS_WEAK_ALIAS - it is likely to be more portable. |
| 262 | * Only use VCOS_WEAK_ALIAS_STR if you need to do pre-processor mangling of the target |
| 263 | * symbol. |
| 264 | */ |
| 265 | #if defined(__GNUC__) || defined(_VCOS_METAWARE) |
| 266 | /* N.B. gcc allows __attribute__ after parameter list, but hcvc seems to silently ignore it. */ |
| 267 | # define VCOS_WEAK_ALIAS_STR(ret_type, alias_name, param_list, target_name) \ |
| 268 | __attribute__ ((weak, alias(target_name))) ret_type alias_name param_list |
| 269 | #else |
| 270 | # define VCOS_WEAK_ALIAS_STR(ret_type, alias, params, target) VCOS_CASSERT(0) |
| 271 | #endif |
| 272 | |
| 273 | #if defined(__GNUC__) |
| 274 | #define VCOS_DEPRECATED(msg) __attribute__((deprecated(msg))) |
| 275 | #else |
| 276 | #define VCOS_DEPRECATED(msg) |
| 277 | #endif |
| 278 | |
| 279 | #endif |
| 280 | |