|
Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
|
00001 /* RapicornCDefs - C compatible definitions 00002 * Copyright (C) 2006 Tim Janik 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * A copy of the GNU Lesser General Public License should ship along 00015 * with this library; if not, see http://www.gnu.org/copyleft/. 00016 */ 00017 #ifndef __RAPICORN_CDEFS_H__ 00018 #define __RAPICORN_CDEFS_H__ 00019 00020 #include <rcore/rapicornconfig.h> /* _GNU_SOURCE */ 00021 #include <stdbool.h> 00022 #include <stdarg.h> 00023 #include <stddef.h> /* NULL */ 00024 #include <sys/types.h> /* uint, ssize */ 00025 #include <stdint.h> /* uint64_t */ 00026 #include <limits.h> /* {INT|CHAR|...}_{MIN|MAX} */ 00027 #include <float.h> /* {FLT|DBL}_{MIN|MAX|EPSILON} */ 00028 00029 RAPICORN_EXTERN_C_BEGIN(); 00030 00031 /* --- standard macros --- */ 00032 #ifndef FALSE 00033 # define FALSE false 00034 #endif 00035 #ifndef TRUE 00036 # define TRUE true 00037 #endif 00038 #define RAPICORN_ABS(a) ((a) > -(a) ? (a) : -(a)) 00039 #define RAPICORN_MIN(a,b) ((a) <= (b) ? (a) : (b)) 00040 #define RAPICORN_MAX(a,b) ((a) >= (b) ? (a) : (b)) 00041 #define RAPICORN_CLAMP(v,mi,ma) ((v) < (mi) ? (mi) : ((v) > (ma) ? (ma) : (v))) 00042 #define RAPICORN_ARRAY_SIZE(array) (sizeof (array) / sizeof ((array)[0])) 00043 #undef ABS 00044 #define ABS RAPICORN_ABS 00045 #undef MIN 00046 #define MIN RAPICORN_MIN 00047 #undef MAX 00048 #define MAX RAPICORN_MAX 00049 #undef CLAMP 00050 #define CLAMP RAPICORN_CLAMP 00051 #undef ARRAY_SIZE 00052 #define ARRAY_SIZE RAPICORN_ARRAY_SIZE 00053 #undef EXTERN_C 00054 #ifdef __cplusplus 00055 #define EXTERN_C extern "C" 00056 #else 00057 #define EXTERN_C extern 00058 #endif 00059 #undef STRFUNC 00060 #define STRFUNC RAPICORN_SIMPLE_FUNCTION 00061 #if !defined (INT64_MAX) || !defined (INT64_MIN) || !defined (UINT64_MAX) 00062 #ifdef LLONG_MAX /* some gcc versions ship limits.h that fail to define LLONG_MAX for C99 */ 00063 # define INT64_MAX LLONG_MAX // +9223372036854775807LL 00064 # define INT64_MIN LLONG_MIN // -9223372036854775808LL 00065 # define UINT64_MAX ULLONG_MAX // +18446744073709551615LLU 00066 #else /* !LLONG_MAX but gcc always has __LONG_LONG_MAX__ */ 00067 # define INT64_MAX __LONG_LONG_MAX__ 00068 # define INT64_MIN (-INT64_MAX - 1LL) 00069 # define UINT64_MAX (INT64_MAX * 2ULL + 1ULL) 00070 #endif 00071 #endif 00072 00073 /* --- likelyness hinting --- */ 00074 #define RAPICORN__BOOL(expr) __extension__ ({ bool _rapicorn__bool; if (expr) _rapicorn__bool = 1; else _rapicorn__bool = 0; _rapicorn__bool; }) 00075 #define RAPICORN_ISLIKELY(expr) __builtin_expect (RAPICORN__BOOL (expr), 1) 00076 #define RAPICORN_UNLIKELY(expr) __builtin_expect (RAPICORN__BOOL (expr), 0) 00077 #define RAPICORN_LIKELY RAPICORN_ISLIKELY 00078 00079 /* --- assertions and runtime errors --- */ 00080 #ifndef __cplusplus 00081 #define RAPICORN_RETURN_IF_FAIL(e) do { if (RAPICORN_ISLIKELY (e)) break; RAPICORN__RUNTIME_PROBLEM ('R', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, "%s", #e); return; } while (0) 00082 #define RAPICORN_RETURN_VAL_IF_FAIL(e,v) do { if (RAPICORN_ISLIKELY (e)) break; RAPICORN__RUNTIME_PROBLEM ('R', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, "%s", #e); return v; } while (0) 00083 #define RAPICORN_ASSERT(e) do { if (RAPICORN_ISLIKELY (e)) break; RAPICORN__RUNTIME_PROBLEM ('A', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, "%s", #e); while (1) *(void*volatile*)0; } while (0) 00084 #define RAPICORN_ASSERT_NOT_REACHED() do { RAPICORN__RUNTIME_PROBLEM ('N', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, NULL); RAPICORN_ABORT_NORETURN(); } while (0) 00085 #define RAPICORN_WARNING(...) do { RAPICORN__RUNTIME_PROBLEM ('W', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, __VA_ARGS__); } while (0) 00086 #define RAPICORN_ERROR(...) do { RAPICORN__RUNTIME_PROBLEM ('E', RAPICORN_LOG_DOMAIN, __FILE__, __LINE__, RAPICORN_SIMPLE_FUNCTION, __VA_ARGS__); RAPICORN_ABORT_NORETURN(); } while (0) 00087 #define RAPICORN_ABORT_NORETURN() rapicorn_abort_noreturn() 00088 #endif 00089 00090 /* --- convenient aliases --- */ 00091 #ifdef RAPICORN_CONVENIENCE 00092 #define ISLIKELY RAPICORN_ISLIKELY 00093 #define UNLIKELY RAPICORN_UNLIKELY 00094 #define LIKELY RAPICORN_LIKELY 00095 #define STRINGIFY RAPICORN_CPP_STRINGIFY 00096 #endif 00097 00098 /* --- preprocessor pasting --- */ 00099 #define RAPICORN_CPP_PASTE4i(a,b,c,d) a ## b ## c ## d 00100 #define RAPICORN_CPP_PASTE4(a,b,c,d) RAPICORN_CPP_PASTE4i (a,b,c,d) 00101 #define RAPICORN_CPP_PASTE3i(a,b,c) a ## b ## c /* indirection required to expand __LINE__ etc */ 00102 #define RAPICORN_CPP_PASTE3(a,b,c) RAPICORN_CPP_PASTE3i (a,b,c) 00103 #define RAPICORN_CPP_PASTE2i(a,b) a ## b /* indirection required to expand __LINE__ etc */ 00104 #define RAPICORN_CPP_PASTE2(a,b) RAPICORN_CPP_PASTE2i (a,b) 00105 #define RAPICORN_CPP_STRINGIFYi(s) #s /* indirection required to expand __LINE__ etc */ 00106 #define RAPICORN_CPP_STRINGIFY(s) RAPICORN_CPP_STRINGIFYi (s) 00107 #define RAPICORN_STATIC_ASSERT_NAMED(expr,asname) typedef struct { char asname[(expr) ? 1 : -1]; } RAPICORN_CPP_PASTE2 (Rapicorn_StaticAssertion_LINE, __LINE__) 00108 #define RAPICORN_STATIC_ASSERT(expr) RAPICORN_STATIC_ASSERT_NAMED (expr, compile_time_assertion_failed) 00109 00110 /* --- attributes --- */ 00111 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) 00112 #define RAPICORN_PURE __attribute__ ((__pure__)) 00113 #define RAPICORN_MALLOC __attribute__ ((__malloc__)) 00114 #define RAPICORN_PRINTF(format_idx, arg_idx) __attribute__ ((__format__ (__printf__, format_idx, arg_idx))) 00115 #define RAPICORN_SCANF(format_idx, arg_idx) __attribute__ ((__format__ (__scanf__, format_idx, arg_idx))) 00116 #define RAPICORN_FORMAT(arg_idx) __attribute__ ((__format_arg__ (arg_idx))) 00117 #define RAPICORN_SENTINEL __attribute__ ((__sentinel__)) 00118 #define RAPICORN_NORETURN __attribute__ ((__noreturn__)) 00119 #define RAPICORN_CONST __attribute__ ((__const__)) 00120 #define RAPICORN_UNUSED __attribute__ ((__unused__)) 00121 #define RAPICORN_NO_INSTRUMENT __attribute__ ((__no_instrument_function__)) 00122 #define RAPICORN_DEPRECATED __attribute__ ((__deprecated__)) 00123 #define RAPICORN_ALWAYS_INLINE __attribute__ ((always_inline)) 00124 #define RAPICORN_NEVER_INLINE __attribute__ ((noinline)) 00125 #define RAPICORN_CONSTRUCTOR __attribute__ ((constructor,used)) /* gcc-3.3 also needs "used" to emit code */ 00126 #define RAPICORN_MAY_ALIAS __attribute__ ((may_alias)) 00127 #else /* !__GNUC__ */ 00128 #define RAPICORN_PURE 00129 #define RAPICORN_MALLOC 00130 #define RAPICORN_PRINTF(format_idx, arg_idx) 00131 #define RAPICORN_SCANF(format_idx, arg_idx) 00132 #define RAPICORN_FORMAT(arg_idx) 00133 #define RAPICORN_SENTINEL 00134 #define RAPICORN_NORETURN 00135 #define RAPICORN_CONST 00136 #define RAPICORN_UNUSED 00137 #define RAPICORN_NO_INSTRUMENT 00138 #define RAPICORN_DEPRECATED 00139 #define RAPICORN_ALWAYS_INLINE 00140 #define RAPICORN_NEVER_INLINE 00141 #define RAPICORN_CONSTRUCTOR 00142 #define RAPICORN_MAY_ALIAS 00143 #error Failed to detect a recent GCC version (>= 3.3) 00144 #endif /* !__GNUC__ */ 00145 #if defined __GNUC__ && defined __cplusplus 00146 #define RAPICORN_SIMPLE_FUNCTION (::Rapicorn::string_from_pretty_function_name (__PRETTY_FUNCTION__).c_str()) 00147 #else 00148 #define RAPICORN_SIMPLE_FUNCTION (__func__) 00149 #endif 00150 00151 /* --- provide canonical integer types --- */ 00152 #if RAPICORN_SIZEOF_SYS_TYPESH_UINT == 0 00153 typedef unsigned int uint; /* for systems that don't define uint in types.h */ 00154 #else 00155 RAPICORN_STATIC_ASSERT (RAPICORN_SIZEOF_SYS_TYPESH_UINT == 4); 00156 #endif 00157 RAPICORN_STATIC_ASSERT (sizeof (uint) == 4); 00158 typedef uint8_t RapicornUInt8; // __attribute__ ((__mode__ (__QI__))) 00159 typedef uint16_t RapicornUInt16; // __attribute__ ((__mode__ (__HI__))) 00160 typedef uint32_t RapicornUInt32; // __attribute__ ((__mode__ (__SI__))) 00161 typedef unsigned long long int RapicornUInt64; // __attribute__ ((__mode__ (__DI__))) 00162 // typedef uint64_t RapicornUInt64; // uint64_t is a long on AMD64 which breaks printf 00163 // Using stdint.h defines here for type compatibility with standard APIs (references, printf, ...) 00164 // provided by rapicorncdefs.h: uint; 00165 RAPICORN_STATIC_ASSERT (sizeof (RapicornUInt8) == 1); 00166 RAPICORN_STATIC_ASSERT (sizeof (RapicornUInt16) == 2); 00167 RAPICORN_STATIC_ASSERT (sizeof (RapicornUInt32) == 4); 00168 RAPICORN_STATIC_ASSERT (sizeof (RapicornUInt64) == 8); 00169 typedef int8_t RapicornInt8; // __attribute__ ((__mode__ (__QI__))) 00170 typedef int16_t RapicornInt16; // __attribute__ ((__mode__ (__HI__))) 00171 typedef int32_t RapicornInt32; // __attribute__ ((__mode__ (__SI__))) 00172 typedef signed long long int RapicornInt64; // __attribute__ ((__mode__ (__DI__))) 00173 // typedef int64_t RapicornInt64; // int64_t is a long on AMD64 which breaks printf 00174 // provided by compiler int; 00175 RAPICORN_STATIC_ASSERT (sizeof (RapicornInt8) == 1); 00176 RAPICORN_STATIC_ASSERT (sizeof (RapicornInt16) == 2); 00177 RAPICORN_STATIC_ASSERT (sizeof (RapicornInt32) == 4); 00178 RAPICORN_STATIC_ASSERT (sizeof (RapicornInt64) == 8); 00179 typedef RapicornUInt32 RapicornUnichar; 00180 RAPICORN_STATIC_ASSERT (sizeof (RapicornUnichar) == 4); 00181 00182 00183 /* --- path handling --- */ 00184 #ifdef RAPICORN_OS_WIN32 00185 #define RAPICORN_DIR_SEPARATOR '\\' 00186 #define RAPICORN_DIR_SEPARATOR_S "\\" 00187 #define RAPICORN_SEARCHPATH_SEPARATOR ';' 00188 #define RAPICORN_SEARCHPATH_SEPARATOR_S ";" 00189 #else /* !RAPICORN_OS_WIN32 */ 00190 #define RAPICORN_DIR_SEPARATOR '/' 00191 #define RAPICORN_DIR_SEPARATOR_S "/" 00192 #define RAPICORN_SEARCHPATH_SEPARATOR ':' 00193 #define RAPICORN_SEARCHPATH_SEPARATOR_S ":" 00194 #endif /* !RAPICORN_OS_WIN32 */ 00195 #define RAPICORN_IS_DIR_SEPARATOR(c) ((c) == RAPICORN_DIR_SEPARATOR) 00196 #define RAPICORN_IS_SEARCHPATH_SEPARATOR(c) ((c) == RAPICORN_SEARCHPATH_SEPARATOR) 00197 00198 /* --- CPU info --- */ 00199 typedef struct { 00200 /* architecture name */ 00201 const char *machine; 00202 /* CPU Vendor ID */ 00203 const char *cpu_vendor; 00204 /* CPU features on X86 */ 00205 uint x86_fpu : 1, x86_ssesys : 1, x86_tsc : 1, x86_htt : 1; 00206 uint x86_mmx : 1, x86_mmxext : 1, x86_3dnow : 1, x86_3dnowext : 1; 00207 uint x86_sse : 1, x86_sse2 : 1, x86_sse3 : 1, x86_sse4 : 1; 00208 } RapicornCPUInfo; 00209 00210 /* --- Thread info --- */ 00211 typedef enum { 00212 RAPICORN_THREAD_UNKNOWN = '?', 00213 RAPICORN_THREAD_RUNNING = 'R', 00214 RAPICORN_THREAD_SLEEPING = 'S', 00215 RAPICORN_THREAD_DISKWAIT = 'D', 00216 RAPICORN_THREAD_TRACED = 'T', 00217 RAPICORN_THREAD_PAGING = 'W', 00218 RAPICORN_THREAD_ZOMBIE = 'Z', 00219 RAPICORN_THREAD_DEAD = 'X', 00220 } RapicornThreadState; 00221 typedef struct { 00222 int thread_id; 00223 char *name; 00224 uint aborted : 1; 00225 RapicornThreadState state; 00226 int priority; /* nice value */ 00227 int processor; /* running processor # */ 00228 RapicornUInt64 utime; /* user time */ 00229 RapicornUInt64 stime; /* system time */ 00230 RapicornUInt64 cutime; /* user time of dead children */ 00231 RapicornUInt64 cstime; /* system time of dead children */ 00232 } RapicornThreadInfo; 00233 00234 /* --- threading ABI --- */ 00235 typedef struct _RapicornThread RapicornThread; 00236 typedef void (*RapicornThreadFunc) (void *user_data); 00237 typedef void (*RapicornThreadWakeup) (void *wakeup_data); 00238 typedef union { 00239 void *cond_pointer; 00240 RapicornUInt8 cond_dummy[MAX (8, RAPICORN_SIZEOF_PTH_COND_T)]; 00241 } RapicornCond; 00242 typedef union { 00243 void *mutex_pointer; 00244 RapicornUInt8 mutex_dummy[MAX (8, RAPICORN_SIZEOF_PTH_MUTEX_T)]; 00245 } RapicornMutex; 00246 typedef struct { 00247 RapicornMutex mutex; 00248 RapicornThread *owner; 00249 uint depth; 00250 } RapicornRecMutex; 00251 typedef struct { 00252 RapicornThread* (*thread_new) (const char *name); 00253 RapicornThread* (*thread_ref) (RapicornThread *thread); 00254 RapicornThread* (*thread_ref_sink) (RapicornThread *thread); 00255 void (*thread_unref) (RapicornThread *thread); 00256 bool (*thread_start) (RapicornThread *thread, 00257 RapicornThreadFunc func, 00258 void *user_data); 00259 RapicornThread* (*thread_self) (void); 00260 void* (*thread_selfxx) (void); 00261 void* (*thread_getxx) (RapicornThread *thread); 00262 bool (*thread_setxx) (RapicornThread *thread, 00263 void *xxdata); 00264 int (*thread_pid) (RapicornThread *thread); 00265 const char* (*thread_name) (RapicornThread *thread); 00266 void (*thread_set_name) (const char *newname); 00267 bool (*thread_sleep) (RapicornInt64 max_useconds); 00268 void (*thread_wakeup) (RapicornThread *thread); 00269 void (*thread_awake_after) (RapicornUInt64 stamp); 00270 void (*thread_emit_wakeups) (RapicornUInt64 wakeup_stamp); 00271 void (*thread_set_wakeup) (RapicornThreadWakeup wakeup_func, 00272 void *wakeup_data, 00273 void (*destroy_data) (void*)); 00274 void (*thread_abort) (RapicornThread *thread); 00275 void (*thread_queue_abort) (RapicornThread *thread); 00276 bool (*thread_aborted) (void); 00277 bool (*thread_get_aborted) (RapicornThread *thread); 00278 bool (*thread_get_running) (RapicornThread *thread); 00279 void (*thread_wait_for_exit) (RapicornThread *thread); 00280 void (*thread_yield) (void); 00281 void (*thread_exit) (void *retval) RAPICORN_NORETURN; 00282 void (*thread_set_handle) (RapicornThread *handle); 00283 RapicornThread* (*thread_get_handle) (void); 00284 RapicornThreadInfo* (*info_collect) (RapicornThread *thread); 00285 void (*info_free) (RapicornThreadInfo *info); 00286 void* (*qdata_get) (uint glib_quark); 00287 void (*qdata_set) (uint glib_quark, 00288 void *data, 00289 void (*destroy_data) (void*)); 00290 void* (*qdata_steal) (uint glib_quark); 00291 } RapicornThreadTable; 00292 00293 /* --- implementation bits --- */ 00294 /* the above macros rely on a problem handler macro: */ 00295 // RAPICORN__RUNTIME_PROBLEM(ErrorWarningReturnAssertNotreach,domain,file,line,funcname,exprformat,...); // noreturn cases: 'E', 'A', 'N' 00296 extern inline void rapicorn_abort_noreturn (void) RAPICORN_NORETURN; 00297 extern inline void rapicorn_abort_noreturn (void) { while (1) *(void*volatile*)0; } 00298 RAPICORN_EXTERN_C_END(); 00299 00300 #endif /* __RAPICORN_CDEFS_H__ */ 00301 00302 /* vim:set ts=8 sts=2 sw=2: */
1.7.4