diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-03-16 12:23:50 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-03-16 14:58:12 -0400 |
commit | 7c9f121efe7ee6afafad8b294974f5498054559b (patch) | |
tree | f87d863242a83d1b519ab113ac76aa21ede2f710 | |
parent | 6b9c54820015f69e667ed54441e83042c9a84cc1 (diff) |
Add PIXMAN_DEFINE_THREAD_LOCAL() and PIXMAN_GET_THREAD_LOCAL() macros
These macros hide the various types of thread local support. On Linux
and Unix, they expand to just __thread. On Microsoft Visual C++, they
expand to __declspec(thread).
On OS X and other systems that don't have __thread, they expand to a
complicated concoction that uses pthread_once() and
pthread_get/set_specific() to get thread local variables.
-rw-r--r-- | pixman/pixman-compiler.h | 63 | ||||
-rw-r--r-- | pixman/pixman.c | 37 |
2 files changed, 79 insertions, 21 deletions
diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h index 5aeef86..a4e3f88 100644 --- a/pixman/pixman-compiler.h +++ b/pixman/pixman-compiler.h @@ -70,11 +70,62 @@ #endif /* TLS */ -#if (defined (__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR >= 3) || __GNUC__ > 3)) || defined(__SUNPRO_C) -# define THREAD_LOCAL __thread -#elif defined (_MSC_VER) -# define THREAD_LOCAL __declspec(thread) +#if defined(TOOLCHAIN_SUPPORTS__THREAD) + +# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ + static __thread type name +# define PIXMAN_GET_THREAD_LOCAL(name) \ + (&name) + +#elif defined(_MSC_VER) + +# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ + static __declspec(thread) type name +# define PIXMAN_GET_THREAD_LOCAL(name) \ + (&name) + +#elif defined(HAVE_PTHREAD_SETSPECIFIC) + +#include <pthread.h> + +# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ + static pthread_once_t tls_ ## name ## _once_control = PTHREAD_ONCE_INIT; \ + static pthread_key_t tls_ ## name ## _key; \ + \ + static void \ + tls_ ## name ## _make_key (void) \ + { \ + pthread_key_create (&tls_ ## name ## _key, NULL); \ + } \ + \ + static type * \ + tls_ ## name ## _alloc (key) \ + { \ + type *value = malloc (sizeof (type)); \ + if (value) \ + pthread_setspecific (key, value); \ + return value; \ + } \ + \ + static force_inline type * \ + tls_ ## name ## _get (key) \ + { \ + type *value = NULL; \ + if (pthread_once (&tls_ ## name ## _once_control, \ + tls_ ## name ## _make_key) == 0) \ + { \ + value = pthread_getspecific (tls_ ## name ## _key); \ + if (!value) \ + value = tls_ ## name ## _alloc (key); \ + } \ + return value; \ + } + +# define PIXMAN_GET_THREAD_LOCAL(name) \ + tls_ ## name ## _get (tls_ ## name ## _key) + #else -# warning "unknown compiler" -# define THREAD_LOCAL __thread + +# error "Unknown thread local support for this system" + #endif diff --git a/pixman/pixman.c b/pixman/pixman.c index c71617e..68483a0 100644 --- a/pixman/pixman.c +++ b/pixman/pixman.c @@ -499,6 +499,15 @@ image_covers (pixman_image_t *image, return TRUE; } +#define N_CACHED_FAST_PATHS 8 + +typedef struct +{ + pixman_fast_path_t cache [N_CACHED_FAST_PATHS]; +} cache_t; + +PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache); + static void do_composite (pixman_implementation_t *imp, pixman_op_t op, @@ -514,8 +523,6 @@ do_composite (pixman_implementation_t *imp, int width, int height) { -#define N_CACHED_FAST_PATHS 8 - static THREAD_LOCAL pixman_fast_path_t tls_cache[N_CACHED_FAST_PATHS]; pixman_format_code_t src_format, mask_format, dest_format; uint32_t src_flags, mask_flags, dest_flags; pixman_region32_t region; @@ -527,8 +534,8 @@ do_composite (pixman_implementation_t *imp, uint32_t *dest_bits; int dest_dx, dest_dy; pixman_bool_t need_workaround; - pixman_fast_path_t *cache; const pixman_fast_path_t *info; + cache_t *cache; int i; src_format = src->common.extended_format_code; @@ -597,11 +604,11 @@ do_composite (pixman_implementation_t *imp, return; /* Check cache for fast paths */ - cache = tls_cache; + cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache); for (i = 0; i < N_CACHED_FAST_PATHS; ++i) { - info = &(cache[i]); + info = &(cache->cache[i]); /* Note that we check for equality here, not whether * the cached fast path matches. This is to prevent @@ -677,16 +684,16 @@ found: pixman_composite_func_t func = info->func; while (i--) - cache[i + 1] = cache[i]; - - cache[0].op = op; - cache[0].src_format = src_format; - cache[0].src_flags = src_flags; - cache[0].mask_format = mask_format; - cache[0].mask_flags = mask_flags; - cache[0].dest_format = dest_format; - cache[0].dest_flags = dest_flags; - cache[0].func = func; + cache->cache[i + 1] = cache->cache[i]; + + cache->cache[0].op = op; + cache->cache[0].src_format = src_format; + cache->cache[0].src_flags = src_flags; + cache->cache[0].mask_format = mask_format; + cache->cache[0].mask_flags = mask_flags; + cache->cache[0].dest_format = dest_format; + cache->cache[0].dest_flags = dest_flags; + cache->cache[0].func = func; } out: |