Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | 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. #ifndef INT16_MIN
  22. # define INT16_MIN              (-32767-1)
  23. #endif
  24.  
  25. #ifndef INT16_MAX
  26. # define INT16_MAX              (32767)
  27. #endif
  28.  
  29. #ifndef INT32_MIN
  30. # define INT32_MIN              (-2147483647-1)
  31. #endif
  32.  
  33. #ifndef INT32_MAX
  34. # define INT32_MAX              (2147483647)
  35. #endif
  36.  
  37. #ifndef UINT32_MIN
  38. # define UINT32_MIN             (0)
  39. #endif
  40.  
  41. #ifndef UINT32_MAX
  42. # define UINT32_MAX             (4294967295U)
  43. #endif
  44.  
  45. #ifndef M_PI
  46. # define M_PI                   3.14159265358979323846
  47. #endif
  48.  
  49. #ifdef _MSC_VER
  50. /* 'inline' is available only in C++ in MSVC */
  51. #   define inline __inline
  52. #   define force_inline __forceinline
  53. #   define noinline __declspec(noinline)
  54. #elif defined __GNUC__ || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
  55. #   define inline __inline__
  56. #   define force_inline __inline__ __attribute__ ((__always_inline__))
  57. #   define noinline __attribute__((noinline))
  58. #else
  59. #   ifndef force_inline
  60. #      define force_inline inline
  61. #   endif
  62. #   ifndef noinline
  63. #      define noinline
  64. #   endif
  65. #endif
  66.  
  67. /* GCC visibility */
  68. #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(_WIN32)
  69. #   define PIXMAN_EXPORT __attribute__ ((visibility("default")))
  70. /* Sun Studio 8 visibility */
  71. #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
  72. #   define PIXMAN_EXPORT __global
  73. #else
  74. #   define PIXMAN_EXPORT
  75. #endif
  76.  
  77. /* TLS */
  78. #if defined(PIXMAN_NO_TLS)
  79.  
  80. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  81.     static type name
  82. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  83.     (&name)
  84.  
  85. #elif defined(TOOLCHAIN_SUPPORTS__THREAD)
  86.  
  87. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  88.     static __thread type name
  89. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  90.     (&name)
  91.  
  92. #elif defined(__MINGW32__)
  93.  
  94. #   define _NO_W32_PSEUDO_MODIFIERS
  95. #   include <windows.h>
  96.  
  97. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  98.     static volatile int tls_ ## name ## _initialized = 0;               \
  99.     static void *tls_ ## name ## _mutex = NULL;                         \
  100.     static unsigned tls_ ## name ## _index;                             \
  101.                                                                         \
  102.     static type *                                                       \
  103.     tls_ ## name ## _alloc (void)                                       \
  104.     {                                                                   \
  105.         type *value = calloc (1, sizeof (type));                        \
  106.         if (value)                                                      \
  107.             TlsSetValue (tls_ ## name ## _index, value);                \
  108.         return value;                                                   \
  109.     }                                                                   \
  110.                                                                         \
  111.     static force_inline type *                                          \
  112.     tls_ ## name ## _get (void)                                         \
  113.     {                                                                   \
  114.         type *value;                                                    \
  115.         if (!tls_ ## name ## _initialized)                              \
  116.         {                                                               \
  117.             if (!tls_ ## name ## _mutex)                                \
  118.             {                                                           \
  119.                 void *mutex = CreateMutexA (NULL, 0, NULL);             \
  120.                 if (InterlockedCompareExchangePointer (                 \
  121.                         &tls_ ## name ## _mutex, mutex, NULL) != NULL)  \
  122.                 {                                                       \
  123.                     CloseHandle (mutex);                                \
  124.                 }                                                       \
  125.             }                                                           \
  126.             WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF);   \
  127.             if (!tls_ ## name ## _initialized)                          \
  128.             {                                                           \
  129.                 tls_ ## name ## _index = TlsAlloc ();                   \
  130.                 tls_ ## name ## _initialized = 1;                       \
  131.             }                                                           \
  132.             ReleaseMutex (tls_ ## name ## _mutex);                      \
  133.         }                                                               \
  134.         if (tls_ ## name ## _index == 0xFFFFFFFF)                       \
  135.             return NULL;                                                \
  136.         value = TlsGetValue (tls_ ## name ## _index);                   \
  137.         if (!value)                                                     \
  138.             value = tls_ ## name ## _alloc ();                          \
  139.         return value;                                                   \
  140.     }
  141.  
  142. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  143.     tls_ ## name ## _get ()
  144.  
  145. #elif defined(_MSC_VER)
  146.  
  147. #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                       \
  148.     static __declspec(thread) type name
  149. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  150.     (&name)
  151.  
  152. #elif defined(HAVE_PTHREAD_SETSPECIFIC)
  153.  
  154. #include <pthread.h>
  155.  
  156. #  define PIXMAN_DEFINE_THREAD_LOCAL(type, name)                        \
  157.     static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \
  158.     static pthread_key_t tls_ ## name ## _key;                          \
  159.                                                                         \
  160.     static void                                                         \
  161.     tls_ ## name ## _destroy_value (void *value)                        \
  162.     {                                                                   \
  163.         free (value);                                                   \
  164.     }                                                                   \
  165.                                                                         \
  166.     static void                                                         \
  167.     tls_ ## name ## _make_key (void)                                    \
  168.     {                                                                   \
  169.         pthread_key_create (&tls_ ## name ## _key,                      \
  170.                             tls_ ## name ## _destroy_value);            \
  171.     }                                                                   \
  172.                                                                         \
  173.     static type *                                                       \
  174.     tls_ ## name ## _alloc (void)                                       \
  175.     {                                                                   \
  176.         type *value = calloc (1, sizeof (type));                        \
  177.         if (value)                                                      \
  178.             pthread_setspecific (tls_ ## name ## _key, value);          \
  179.         return value;                                                   \
  180.     }                                                                   \
  181.                                                                         \
  182.     static force_inline type *                                          \
  183.     tls_ ## name ## _get (void)                                         \
  184.     {                                                                   \
  185.         type *value = NULL;                                             \
  186.         if (pthread_once (&tls_ ## name ## _once_control,               \
  187.                           tls_ ## name ## _make_key) == 0)              \
  188.         {                                                               \
  189.             value = pthread_getspecific (tls_ ## name ## _key);         \
  190.             if (!value)                                                 \
  191.                 value = tls_ ## name ## _alloc ();                      \
  192.         }                                                               \
  193.         return value;                                                   \
  194.     }                                                                   \
  195.     extern int no_such_variable                                        
  196.  
  197. #   define PIXMAN_GET_THREAD_LOCAL(name)                                \
  198.     tls_ ## name ## _get ()
  199.  
  200. #else
  201.  
  202. #    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."
  203.  
  204. #endif
  205.