Rapicorn - Experimental UI Toolkit - Source Code 10.08.1
rapicorncdefs.h
Go to the documentation of this file.
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: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines