diff options
Diffstat (limited to 'src/gallium/auxiliary')
-rw-r--r-- | src/gallium/auxiliary/draw/draw_pt_util.c | 1 | ||||
-rw-r--r-- | src/gallium/auxiliary/os/os_thread.h | 279 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/rtasm/rtasm_execmem.c | 4 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_atomic.h | 247 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_inlines.h | 2 | ||||
-rw-r--r-- | src/gallium/auxiliary/util/u_ringbuffer.c | 2 |
12 files changed, 537 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pt_util.c b/src/gallium/auxiliary/draw/draw_pt_util.c index 17c3b8cec26..3236d38e6ab 100644 --- a/src/gallium/auxiliary/draw/draw_pt_util.c +++ b/src/gallium/auxiliary/draw/draw_pt_util.c @@ -33,6 +33,7 @@ #include "draw/draw_context.h" #include "draw/draw_private.h" #include "draw/draw_pt.h" +#include "util/u_debug.h" void draw_pt_split_prim(unsigned prim, unsigned *first, unsigned *incr) { diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h new file mode 100644 index 00000000000..63108605d3a --- /dev/null +++ b/src/gallium/auxiliary/os/os_thread.h @@ -0,0 +1,279 @@ +/************************************************************************** + * + * Copyright 1999-2006 Brian Paul + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * @file + * + * Thread, mutex, condition var and thread-specific data functions. + */ + + +#ifndef OS_THREAD_H_ +#define OS_THREAD_H_ + + +#include "pipe/p_compiler.h" +#include "util/u_debug.h" /* for assert */ + + +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + +#include <pthread.h> /* POSIX threads headers */ +#include <stdio.h> /* for perror() */ + +#define PIPE_THREAD_HAVE_CONDVAR + +typedef pthread_t pipe_thread; + +#define PIPE_THREAD_ROUTINE( name, param ) \ + void *name( void *param ) + +static INLINE pipe_thread pipe_thread_create( void *(* routine)( void *), void *param ) +{ + pipe_thread thread; + if (pthread_create( &thread, NULL, routine, param )) + return 0; + return thread; +} + +static INLINE int pipe_thread_wait( pipe_thread thread ) +{ + return pthread_join( thread, NULL ); +} + +static INLINE int pipe_thread_destroy( pipe_thread thread ) +{ + return pthread_detach( thread ); +} + +typedef pthread_mutex_t pipe_mutex; +typedef pthread_cond_t pipe_condvar; + +#define pipe_static_mutex(mutex) \ + static pipe_mutex mutex = PTHREAD_MUTEX_INITIALIZER + +#define pipe_mutex_init(mutex) \ + (void) pthread_mutex_init(&(mutex), NULL) + +#define pipe_mutex_destroy(mutex) \ + pthread_mutex_destroy(&(mutex)) + +#define pipe_mutex_lock(mutex) \ + (void) pthread_mutex_lock(&(mutex)) + +#define pipe_mutex_unlock(mutex) \ + (void) pthread_mutex_unlock(&(mutex)) + +#define pipe_static_condvar(mutex) \ + static pipe_condvar mutex = PTHREAD_COND_INITIALIZER + +#define pipe_condvar_init(cond) \ + pthread_cond_init(&(cond), NULL) + +#define pipe_condvar_destroy(cond) \ + pthread_cond_destroy(&(cond)) + +#define pipe_condvar_wait(cond, mutex) \ + pthread_cond_wait(&(cond), &(mutex)) + +#define pipe_condvar_signal(cond) \ + pthread_cond_signal(&(cond)) + +#define pipe_condvar_broadcast(cond) \ + pthread_cond_broadcast(&(cond)) + + +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + +#include <windows.h> + +typedef HANDLE pipe_thread; + +#define PIPE_THREAD_ROUTINE( name, param ) \ + void * WINAPI name( void *param ) + +static INLINE pipe_thread pipe_thread_create( void *(WINAPI * routine)( void *), void *param ) +{ + DWORD id; + return CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) routine, param, 0, &id ); +} + +static INLINE int pipe_thread_wait( pipe_thread thread ) +{ + if (WaitForSingleObject( thread, INFINITE ) == WAIT_OBJECT_0) + return 0; + return -1; +} + +static INLINE int pipe_thread_destroy( pipe_thread thread ) +{ + if (CloseHandle( thread )) + return 0; + return -1; +} + +typedef CRITICAL_SECTION pipe_mutex; + +#define pipe_static_mutex(mutex) \ + /*static*/ pipe_mutex mutex = {0,0,0,0,0,0} + +#define pipe_mutex_init(mutex) \ + InitializeCriticalSection(&mutex) + +#define pipe_mutex_destroy(mutex) \ + DeleteCriticalSection(&mutex) + +#define pipe_mutex_lock(mutex) \ + EnterCriticalSection(&mutex) + +#define pipe_mutex_unlock(mutex) \ + LeaveCriticalSection(&mutex) + +/* XXX: dummy definitions, make it compile */ + +typedef unsigned pipe_condvar; + +#define pipe_condvar_init(condvar) \ + (void) condvar + +#define pipe_condvar_broadcast(condvar) \ + (void) condvar + +#else + +/** Dummy definitions */ + +typedef unsigned pipe_thread; +typedef unsigned pipe_mutex; +typedef unsigned pipe_condvar; + +#define pipe_static_mutex(mutex) \ + static pipe_mutex mutex = 0 + +#define pipe_mutex_init(mutex) \ + (void) mutex + +#define pipe_mutex_destroy(mutex) \ + (void) mutex + +#define pipe_mutex_lock(mutex) \ + (void) mutex + +#define pipe_mutex_unlock(mutex) \ + (void) mutex + +#define pipe_static_condvar(condvar) \ + static unsigned condvar = 0 + +#define pipe_condvar_init(condvar) \ + (void) condvar + +#define pipe_condvar_destroy(condvar) \ + (void) condvar + +#define pipe_condvar_wait(condvar, mutex) \ + (void) condvar + +#define pipe_condvar_signal(condvar) \ + (void) condvar + +#define pipe_condvar_broadcast(condvar) \ + (void) condvar + + +#endif /* PIPE_OS_? */ + + + +/* + * Thread-specific data. + */ + +typedef struct { +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + pthread_key_t key; +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + DWORD key; +#endif + int initMagic; +} pipe_tsd; + + +#define PIPE_TSD_INIT_MAGIC 0xff8adc98 + + +static INLINE void +pipe_tsd_init(pipe_tsd *tsd) +{ +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) { + perror("pthread_key_create(): failed to allocate key for thread specific data"); + exit(-1); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); +#endif + tsd->initMagic = PIPE_TSD_INIT_MAGIC; +} + +static INLINE void * +pipe_tsd_get(pipe_tsd *tsd) +{ + if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { + pipe_tsd_init(tsd); + } +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + return pthread_getspecific(tsd->key); +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); + return NULL; +#else + assert(0); + return NULL; +#endif +} + +static INLINE void +pipe_tsd_set(pipe_tsd *tsd, void *value) +{ + if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) { + pipe_tsd_init(tsd); + } +#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU) + if (pthread_setspecific(tsd->key, value) != 0) { + perror("pthread_set_specific() failed"); + exit(-1); + } +#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) + assert(0); +#else + assert(0); +#endif +} + + + +#endif /* OS_THREAD_H_ */ diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index ba087ac0f34..95eb5f65635 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -44,7 +44,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 7b34c8e3578..c1498318dfb 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -36,7 +36,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_time.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 8f74180a111..93f8960641f 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -35,7 +35,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index 6400fc5b0a3..63195715d68 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -35,7 +35,7 @@ #include "pipe/p_defines.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "util/u_double_list.h" #include "util/u_mm.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 7fd65ed2261..fea234ae8c7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -37,7 +37,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index d21910d0bf0..c445cb578b0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -38,7 +38,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_memory.h" #include "util/u_double_list.h" diff --git a/src/gallium/auxiliary/rtasm/rtasm_execmem.c b/src/gallium/auxiliary/rtasm/rtasm_execmem.c index ffed768f979..65d5ce795be 100644 --- a/src/gallium/auxiliary/rtasm/rtasm_execmem.c +++ b/src/gallium/auxiliary/rtasm/rtasm_execmem.c @@ -32,7 +32,7 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_memory.h" #include "rtasm_execmem.h" @@ -58,7 +58,7 @@ #include <unistd.h> #include <sys/mman.h> -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "util/u_mm.h" #define EXEC_HEAP_SIZE (10*1024*1024) diff --git a/src/gallium/auxiliary/util/u_atomic.h b/src/gallium/auxiliary/util/u_atomic.h new file mode 100644 index 00000000000..1c042c3ede9 --- /dev/null +++ b/src/gallium/auxiliary/util/u_atomic.h @@ -0,0 +1,247 @@ +/** + * Many similar implementations exist. See for example libwsbm + * or the linux kernel include/atomic.h + * + * No copyright claimed on this file. + * + */ + +#ifndef U_ATOMIC_H +#define U_ATOMIC_H + +#include "pipe/p_compiler.h" +#include "pipe/p_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Favor OS-provided implementations. + * + * Where no OS-provided implementation is available, fall back to + * locally coded assembly, compiler intrinsic or ultimately a + * mutex-based implementation. + */ +#if (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \ + defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)) +#define PIPE_ATOMIC_OS_UNLOCKED +#elif defined(PIPE_CC_MSVC) +#define PIPE_ATOMIC_MSVC_INTRINSIC +#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_MSVC_X86 +#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) +#define PIPE_ATOMIC_ASM_GCC_X86 +#elif defined(PIPE_CC_GCC) +#define PIPE_ATOMIC_GCC_INTRINSIC +#else +#error "Unsupported platform" +#endif + + + +#if defined(PIPE_ATOMIC_ASM_GCC_X86) + +#define PIPE_ATOMIC "GCC x86 assembly" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) + ::"memory"); + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm__ __volatile__("lock; incl %0":"+m"(*v)); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm__ __volatile__("lock; decl %0":"+m"(*v)); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} +#endif + + + +/* Implementation using GCC-provided synchronization intrinsics + */ +#if defined(PIPE_ATOMIC_GCC_INTRINSIC) + +#define PIPE_ATOMIC "GCC Sync Intrinsics" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return (__sync_sub_and_fetch(v, 1) == 0); +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + (void) __sync_add_and_fetch(v, 1); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + (void) __sync_sub_and_fetch(v, 1); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return __sync_val_compare_and_swap(v, old, _new); +} +#endif + + + +/* Unlocked version for single threaded environments, such as some + * windows kernel modules. + */ +#if defined(PIPE_ATOMIC_OS_UNLOCKED) + +#define PIPE_ATOMIC "Unlocked" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) +#define p_atomic_dec_zero(_v) ((boolean) --(*(_v))) +#define p_atomic_inc(_v) ((void) (*(_v))++) +#define p_atomic_dec(_v) ((void) (*(_v))--) +#define p_atomic_cmpxchg(_v, old, _new) (*(_v) == old ? *(_v) = (_new) : *(_v)) + +#endif + + +/* Locally coded assembly for MSVC on x86: + */ +#if defined(PIPE_ATOMIC_ASM_MSVC_X86) + +#define PIPE_ATOMIC "MSVC x86 assembly" + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + unsigned char c; + + __asm { + mov eax, [v] + lock dec dword ptr [eax] + sete byte ptr [c] + } + + return c != 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + __asm { + mov eax, [v] + lock inc dword ptr [eax] + } +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + __asm { + mov eax, [v] + lock dec dword ptr [eax] + } +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + int32_t orig; + + __asm { + mov ecx, [v] + mov eax, [old] + mov edx, [_new] + lock cmpxchg [ecx], edx + mov [orig], eax + } + + return orig; +} +#endif + + +#if defined(PIPE_ATOMIC_MSVC_INTRINSIC) + +#define PIPE_ATOMIC "MSVC Intrinsics" + +#include <intrin.h> + +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedCompareExchange) + +#define p_atomic_set(_v, _i) (*(_v) = (_i)) +#define p_atomic_read(_v) (*(_v)) + +static INLINE boolean +p_atomic_dec_zero(int32_t *v) +{ + return _InterlockedDecrement(v) == 0; +} + +static INLINE void +p_atomic_inc(int32_t *v) +{ + _InterlockedIncrement(v); +} + +static INLINE void +p_atomic_dec(int32_t *v) +{ + _InterlockedDecrement(v); +} + +static INLINE int32_t +p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) +{ + return _InterlockedCompareExchange(v, _new, old); +} + +#endif + + + +#ifndef PIPE_ATOMIC +#error "No pipe_atomic implementation selected" +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif /* U_ATOMIC_H */ diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 72a4d6d5083..e95d58ea863 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -33,7 +33,7 @@ #include "pipe/p_state.h" #include "pipe/p_screen.h" #include "util/u_debug.h" -#include "pipe/p_atomic.h" +#include "util/u_atomic.h" #ifdef __cplusplus diff --git a/src/gallium/auxiliary/util/u_ringbuffer.c b/src/gallium/auxiliary/util/u_ringbuffer.c index 3f43a19e018..95d45ebb71f 100644 --- a/src/gallium/auxiliary/util/u_ringbuffer.c +++ b/src/gallium/auxiliary/util/u_ringbuffer.c @@ -1,5 +1,5 @@ -#include "pipe/p_thread.h" +#include "os/os_thread.h" #include "pipe/p_defines.h" #include "util/u_ringbuffer.h" #include "util/u_math.h" |