Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* Pixman uses some non-standard compiler features. This file ensures
  2.  * they exist
  3.  *
  4.  * The features are:
  5.  *
  6.  *    FUNC           must be defined to expand to the current function
  7.  *    PIXMAN_EXPORT  should be defined to whatever is required to
  8.  *                   export functions from a shared library
  9.  *    limits         limits for various types must be defined
  10.  *    inline         must be defined
  11.  *    force_inline   must be defined
  12.  */
  13. #if defined (__GNUC__)
  14. #  define FUNC     ((const char*) (__PRETTY_FUNCTION__))
  15. #elif defined (__sun) || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
  16. #  define FUNC     ((const char*) (__func__))
  17. #else
  18. #  define FUNC     ((const char*) ("???"))
  19. #endif
  20.  
  21. #if defined (__GNUC__)
  22. #  define unlikely(expr) __builtin_expect ((expr), 0)
  23. #else
  24. #  define unlikely(expr)  (expr)
  25. #endif
  26.  
  27. #if defined (__GNUC__)
  28. #  define MAYBE_UNUSED  __attribute__((unused))
  29. #else
  30. #  define MAYBE_UNUSED
  31. #endif
  32.  
  33. #ifndef INT16_MIN
  34. # define INT16_MIN              (-32767-1)
  35. #endif
  36.  
  37. #ifndef INT16_MAX
  38. # define INT16_MAX              (32767)
  39. #endif
  40.  
  41. #ifndef INT32_MIN
  42. # define INT32_MIN              (-2147483647-1)
  43. #endif
  44.  
  45. #ifndef INT32_MAX
  46. # define INT32_MAX              (2147483647)
  47. #endif
  48.  
  49. #ifndef UINT32_MIN
  50. # define UINT32_MIN             (0)
  51. #endif
  52.  
  53. #ifndef UINT32_MAX
  54. # define UINT32_MAX             (4294967295U)
  55. #endif
  56.  
  57. #ifndef INT64_MIN
  58. # define INT64_MIN              (-9223372036854775807-1)
  59. #endif
  60.  
  61. #ifndef INT64_MAX
  62. # define INT64_MAX              (9223372036854775807)
  63. #endif
  64.  
  65. #ifndef SIZE_MAX
  66. # define SIZE_MAX               ((size_t)-1)
  67. #endif
  68.  
  69.  
  70. #ifndef M_PI
  71. # define M_PI                   3.14159265358979323846
  72. #endif
  73.  
  74. #ifdef _MSC_VER
  75. /* 'inline' is available only in C++ in MSVC */
  76. #   define inline __inline
  77. #   define force_inline __forceinline
  78. #   define noinline __declspec(noinline)
  79. #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
  80. #   define inline __inline__
  81. #   define force_inline __inline__ __attribute__ ((__always_inline__))
  82. #   define noinline __attribute__((noinline))
  83. #else
  84. #   ifndef force_inline
  85. #      define force_inline inline
  86. #   endif
  87. #   ifndef noinline
  88. #      define noinline
  89. #   endif
  90. #endif
  91.  
  92. /* GCC visibility */
  93. #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
  94. #   define PIXMAN_EXPORT __attribute__ ((visibility("default")))
  95. /* Sun Studio 8 visibility */
  96. #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
  97. #   define PIXMAN_EXPORT __global
  98. #else
  99. #   define PIXMAN_EXPORT
  100. #endif
  101.  
  102. /* member offsets */
  103. #define CONTAINER_OF(type, member, data)                                \
  104.     ((type *)(((uint8_t *)data) - offsetof (type, member)))
  105.  
  106. /* TLS */
  107. #if defined(PIXMAN_NO_TLS)
  108.  
  109. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  110.     static type name
  111. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  112.     (&name)
  113.  
  114. #elif defined(TLS)
  115.  
  116. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  117.     static TLS type name
  118. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  119.     (&name)
  120.  
  121. #elif defined(__MINGW32__)
  122.  
  123. #   define _NO_W32_PSEUDO_MODIFIERS
  124. #   include <windows.h>
  125.  
  126. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  127.     static volatile int tls_ ## name ## _initialized = 0;               \
  128.     static void *tls_ ## name ## _mutex = NULL;                         \
  129.     static unsigned tls_ ## name ## _index;                             \
  130.                                                                         \
  131.     static type *                                                       \
  132.     tls_ ## name ## _alloc (void)                                       \
  133.     {                                                                   \
  134.         type *value = calloc (1, sizeof (type));                        \
  135.         if (value)                                                      \
  136.             TlsSetValue (tls_ ## name ## _index, value);                \
  137.         return value;                                                   \
  138.     }                                                                   \
  139.                                                                         \
  140.     static force_inline type *                                          \
  141.     tls_ ## name ## _get (void)                                         \
  142.     {                                                                   \
  143.         type *value;                                                    \
  144.         if (!tls_ ## name ## _initialized)                              \
  145.         {                                                               \
  146.             if (!tls_ ## name ## _mutex)                                \
  147.             {                                                           \
  148.                 void *mutex = CreateMutexA (NULL, 0, NULL);             \
  149.                 if (InterlockedCompareExchangePointer (                 \
  150.                         &tls_ ## name ## _mutex, mutex, NULL) != NULL)  \
  151.                 {                                                       \
  152.                     CloseHandle (mutex);                                \
  153.                 }                                                       \
  154.             }                                                           \
  155.             WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF);   \
  156.             if (!tls_ ## name ## _initialized)                          \
  157.             {                                                           \
  158.                 tls_ ## name ## _index = TlsAlloc ();                   \
  159.                 tls_ ## name ## _initialized = 1;                       \
  160.             }                                                           \
  161.             ReleaseMutex (tls_ ## name ## _mutex);                      \
  162.         }                                                               \
  163.         if (tls_ ## name ## _index == 0xFFFFFFFF)                       \
  164.             return NULL;                                                \
  165.         value = TlsGetValue (tls_ ## name ## _index);                   \
  166.         if (!value)                                                     \
  167.             value = tls_ ## name ## _alloc ();                          \
  168.         return value;                                                   \
  169.     }
  170.  
  171. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  172.     tls_ ## name ## _get ()
  173.  
  174. #elif defined(_MSC_VER)
  175.  
  176. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  177.     static __declspec(thread) type name
  178. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  179.     (&name)
  180.  
  181. #elif defined(HAVE_PTHREAD_SETSPECIFIC)
  182.  
  183. #include <pthread.h>
  184.  
  185. #  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                        \
  186.     static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
  187.     static pthread_key_t tls_ ## name ## _key;                          \
  188.                                                                         \
  189.     static void                                                         \
  190.     tls_ ## name ## _destroy_value (void *value)                        \
  191.     {                                                                   \
  192.         free (value);                                                   \
  193.     }                                                                   \
  194.                                                                         \
  195.     static void                                                         \
  196.     tls_ ## name ## _make_key (void)                                    \
  197.     {                                                                   \
  198.         pthread_key_create (&tls_ ## name ## _key,                      \
  199.                             tls_ ## name ## _destroy_value);            \
  200.     }                                                                   \
  201.                                                                         \
  202.     static type *                                                       \
  203.     tls_ ## name ## _alloc (void)                                       \
  204.     {                                                                   \
  205.         type *value = calloc (1, sizeof (type));                        \
  206.         if (value)                                                      \
  207.             pthread_setspecific (tls_ ## name ## _key, value);          \
  208.         return value;                                                   \
  209.     }                                                                   \
  210.                                                                         \
  211.     static force_inline type *                                          \
  212.     tls_ ## name ## _get (void)                                         \
  213.     {                                                                   \
  214.         type *value = NULL;                                             \
  215.         if (pthread_once (&tls_ ## name ## _once_control,               \
  216.                           tls_ ## name ## _make_key) == 0)              \
  217.         {                                                               \
  218.             value = pthread_getspecific (tls_ ## name ## _key);         \
  219.             if (!value)                                                 \
  220.                 value = tls_ ## name ## _alloc ();                      \
  221.         }                                                               \
  222.         return value;                                                   \
  223.     }
  224.  
  225. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  226.     tls_ ## name ## _get ()
  227.  
  228. #else
  229.  
  230. #    error "Unknown thread local support for this system. Pixman will not work with multiple threads. Define PIXMAN_NO_TLS to acknowledge and accept this limitation and compile pixman without thread-safety support."
  231.  
  232. #endif
  233.