diff --git a/contrib/sdk/sources/libsupc++/Makefile b/contrib/sdk/sources/libsupc++/Makefile index dccf32f128..91069eeb4f 100644 --- a/contrib/sdk/sources/libsupc++/Makefile +++ b/contrib/sdk/sources/libsupc++/Makefile @@ -1,5 +1,5 @@ -LIBRARY= libsup++ +LIBRARY= libsupc++ CC=gcc CPP=g++ diff --git a/contrib/sdk/sources/libsupc++/gthr-default.h b/contrib/sdk/sources/libsupc++/gthr-default.h index bc09371e3c..53f8396cc8 100644 --- a/contrib/sdk/sources/libsupc++/gthr-default.h +++ b/contrib/sdk/sources/libsupc++/gthr-default.h @@ -72,8 +72,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include <_mingw.h> #endif -#ifndef ___GLIBCXX_UNUSED_PARAM -#define ___GLIBCXX_UNUSED_PARAM(x) x +#ifndef __UNUSED_PARAM +#define __UNUSED_PARAM(x) x #endif #ifdef _LIBOBJC @@ -295,7 +295,7 @@ __gthread_objc_mutex_unlock (objc_mutex_t mutex) /* Allocate a condition. */ int -__gthread_objc_condition_allocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition)) +__gthread_objc_condition_allocate (objc_condition_t __UNUSED_PARAM(condition)) { /* Unimplemented. */ return -1; @@ -303,7 +303,7 @@ __gthread_objc_condition_allocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(cond /* Deallocate a condition. */ int -__gthread_objc_condition_deallocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition)) +__gthread_objc_condition_deallocate (objc_condition_t __UNUSED_PARAM(condition)) { /* Unimplemented. */ return -1; @@ -311,8 +311,8 @@ __gthread_objc_condition_deallocate (objc_condition_t ___GLIBCXX_UNUSED_PARAM(co /* Wait on the condition */ int -__gthread_objc_condition_wait (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition), - objc_mutex_t ___GLIBCXX_UNUSED_PARAM(mutex)) +__gthread_objc_condition_wait (objc_condition_t __UNUSED_PARAM(condition), + objc_mutex_t __UNUSED_PARAM(mutex)) { /* Unimplemented. */ return -1; @@ -320,7 +320,7 @@ __gthread_objc_condition_wait (objc_condition_t ___GLIBCXX_UNUSED_PARAM(conditio /* Wake up all threads waiting on this condition. */ int -__gthread_objc_condition_broadcast (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition)) +__gthread_objc_condition_broadcast (objc_condition_t __UNUSED_PARAM(condition)) { /* Unimplemented. */ return -1; @@ -328,7 +328,7 @@ __gthread_objc_condition_broadcast (objc_condition_t ___GLIBCXX_UNUSED_PARAM(con /* Wake up one thread waiting on this condition. */ int -__gthread_objc_condition_signal (objc_condition_t ___GLIBCXX_UNUSED_PARAM(condition)) +__gthread_objc_condition_signal (objc_condition_t __UNUSED_PARAM(condition)) { /* Unimplemented. */ return -1; diff --git a/contrib/sdk/sources/libsupc++/gthr_mutex.c b/contrib/sdk/sources/libsupc++/gthr_mutex.c index d750279ec3..f5cb8eb1a6 100644 --- a/contrib/sdk/sources/libsupc++/gthr_mutex.c +++ b/contrib/sdk/sources/libsupc++/gthr_mutex.c @@ -1,11 +1,65 @@ +#include +#include +#include void __mutex_lock(volatile int *val); +static inline int tls_get(int key) +{ + int val; + __asm__ __volatile__( + "movl %%fs:(%1), %0" + :"=r"(val) + :"r"(key)); + + return val; +}; + +typedef struct { + int done; + long started; +} __gthread_once_t; + typedef struct { int counter; void *sema; } __gthread_mutex_t; +typedef struct { + int counter; + int depth; + unsigned long owner; + int sema; +} __gthread_recursive_mutex_t; + + +int +__gthr_win32_once (__gthread_once_t *once, void (*func) (void)) +{ + if (once == NULL || func == NULL) + return EINVAL; + + if (! once->done) + { + if (__sync_add_and_fetch (&(once->started), 1) == 0) + { + (*func) (); + once->done = 1; + } + else + { + /* Another thread is currently executing the code, so wait for it + to finish; yield the CPU in the meantime. If performance + does become an issue, the solution is to use an Event that + we wait on here (and set above), but that implies a place to + create the event before this routine is called. */ + while (! once->done) + delay(1); + } + } + return 0; +} + void __gthr_win32_mutex_init_function (__gthread_mutex_t *mutex) { mutex->counter = 0; @@ -25,3 +79,72 @@ __gthr_win32_mutex_unlock (__gthread_mutex_t *mutex) return 0; } +void +__gthr_win32_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex) +{ + mutex->counter = -1; + mutex->depth = 0; + mutex->owner = 0; + mutex->sema = 0; +} + +void +__gthr_win32_mutex_destroy (__gthread_mutex_t *mutex) +{ } + +int +__gthr_win32_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex) +{ + int me = tls_get(0); + if ( __sync_add_and_fetch(&mutex->counter, 1) == 0) + { + mutex->depth = 1; + mutex->owner = me; + mutex->sema = 1; + } + else if (mutex->owner == me) + { + __sync_sub_and_fetch(&mutex->counter, 1); + ++(mutex->depth); + } + else + { + __mutex_lock(&mutex->sema); + mutex->depth = 1; + mutex->owner = me; + } + return 0; +} + +int +__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex) +{ + int me = tls_get(0); + if (__sync_val_compare_and_swap (&mutex->counter, -1, 0) < 0) + { + mutex->depth = 1; + mutex->owner = me; + mutex->sema = 1; + } + else if (mutex->owner == me) + ++(mutex->depth); + else + return 1; + + return 0; +} + +int +__gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex) +{ + --(mutex->depth); + if (mutex->depth == 0) + { + mutex->owner = 0; + + if (__sync_sub_and_fetch (&mutex->counter, 1) >= 0) + mutex->sema = 0; + } + + return 0; +}