diff options
Diffstat (limited to 'src/osd/modules/sync/sync_ntc.cpp')
-rw-r--r-- | src/osd/modules/sync/sync_ntc.cpp | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/src/osd/modules/sync/sync_ntc.cpp b/src/osd/modules/sync/sync_ntc.cpp index 462c56ee434..c78f67ce64a 100644 --- a/src/osd/modules/sync/sync_ntc.cpp +++ b/src/osd/modules/sync/sync_ntc.cpp @@ -38,16 +38,6 @@ #include <errno.h> #include <sys/time.h> -struct osd_lock { - volatile pthread_t holder; - INT32 count; -#ifdef PTR64 - INT8 padding[52]; // Fill a 64-byte cache line -#else - INT8 padding[56]; // A bit more padding -#endif -}; - struct osd_event { pthread_mutex_t mutex; pthread_cond_t cond; @@ -69,275 +59,6 @@ struct osd_thread { pthread_t thread; }; -struct osd_scalable_lock -{ - struct - { - volatile INT32 haslock; // do we have the lock? - INT32 filler[64/4-1]; // assumes a 64-byte cache line - } slot[WORK_MAX_THREADS]; // one slot per thread - volatile INT32 nextindex; // index of next slot to use -}; - - -//============================================================ -// Scalable Locks -//============================================================ - -osd_scalable_lock *osd_scalable_lock_alloc(void) -{ - osd_scalable_lock *lock; - - lock = (osd_scalable_lock *)calloc(1, sizeof(*lock)); - if (lock == NULL) - return NULL; - - memset(lock, 0, sizeof(*lock)); - lock->slot[0].haslock = TRUE; - return lock; -} - - -INT32 osd_scalable_lock_acquire(osd_scalable_lock *lock) -{ - INT32 myslot = (atomic_increment32(&lock->nextindex) - 1) & (WORK_MAX_THREADS - 1); - -#if defined(__i386__) || defined(__x86_64__) - register INT32 tmp; - __asm__ __volatile__ ( - "1: clr %[tmp] ;" - " xchg %[haslock], %[tmp] ;" - " test %[tmp], %[tmp] ;" - " jne 3f ;" - "2: mov %[haslock], %[tmp] ;" - " test %[tmp], %[tmp] ;" - " jne 1b ;" - " pause ;" - " jmp 2b ;" - "3: " - : [haslock] "+m" (lock->slot[myslot].haslock) - , [tmp] "=&r" (tmp) - : - : "cc" - ); -#elif defined(__ppc__) || defined (__PPC__) || defined(__ppc64__) || defined(__PPC64__) - register INT32 tmp; - __asm__ __volatile__ ( - "1: lwarx %[tmp], 0, %[haslock] \n" - " cmpwi %[tmp], 0 \n" - " bne 3f \n" - "2: lwzx %[tmp], 0, %[haslock] \n" - " cmpwi %[tmp], 0 \n" - " bne 1b \n" - " nop \n" - " nop \n" - " b 2b \n" - "3: li %[tmp], 0 \n" - " stwcx. %[tmp], 0, %[haslock] \n" - " bne- 1b \n" - " lwsync \n" - : [tmp] "=&r" (tmp) - : [haslock] "r" (&lock->slot[myslot].haslock) - : "cr0" - ); -#else - INT32 backoff = 1; - while (!osd_compare_exchange32(&lock->slot[myslot].haslock, TRUE, FALSE)) - { - INT32 backcount; - for (backcount = 0; backcount < backoff; backcount++) - osd_yield_processor(); - backoff <<= 1; - } -#endif - return myslot; -} - - -void osd_scalable_lock_release(osd_scalable_lock *lock, INT32 myslot) -{ -#if defined(__i386__) || defined(__x86_64__) - register INT32 tmp = TRUE; - __asm__ __volatile__ ( - " xchg %[haslock], %[tmp] ;" - : [haslock] "+m" (lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock) - , [tmp] "+r" (tmp) - : - ); -#elif defined(__ppc__) || defined (__PPC__) || defined(__ppc64__) || defined(__PPC64__) - lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock = TRUE; - __asm__ __volatile__ ( " lwsync " : : ); -#else - osd_exchange32(&lock->slot[(myslot + 1) & (WORK_MAX_THREADS - 1)].haslock, TRUE); -#endif -} - -void osd_scalable_lock_free(osd_scalable_lock *lock) -{ - free(lock); -} - -static inline pthread_t osd_compare_exchange_pthread_t(pthread_t volatile *ptr, pthread_t compare, pthread_t exchange) -{ -#ifdef PTR64 - INT64 result = compare_exchange64((INT64 volatile *)ptr, (INT64)compare, (INT64)exchange); -#else - INT32 result = compare_exchange32((INT32 volatile *)ptr, (INT32)compare, (INT32)exchange); -#endif - return (pthread_t)result; -} - -static inline pthread_t osd_exchange_pthread_t(pthread_t volatile *ptr, pthread_t exchange) -{ -#ifdef PTR64 - INT64 result = osd_exchange64((INT64 volatile *)ptr, (INT64)exchange); -#else - INT32 result = atomic_exchange32((INT32 volatile *)ptr, (INT32)exchange); -#endif - return (pthread_t)result; -} - - -//============================================================ -// osd_lock_alloc -//============================================================ - -osd_lock *osd_lock_alloc(void) -{ - osd_lock *lock; - - lock = (osd_lock *)calloc(1, sizeof(osd_lock)); - if (lock == NULL) - return NULL; - - lock->holder = 0; - lock->count = 0; - - return lock; -} - -//============================================================ -// osd_lock_acquire -//============================================================ - -void osd_lock_acquire(osd_lock *lock) -{ - pthread_t current, prev; - - current = pthread_self(); - prev = osd_compare_exchange_pthread_t(&lock->holder, 0, current); - if (prev != nullptr && prev != current) - { - do { - register INT32 spin = 10000; // Convenient spin count - register pthread_t tmp; -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__ ( - "1: pause ;" - " mov %[holder], %[tmp] ;" - " test %[tmp], %[tmp] ;" - " loopne 1b ;" - : [spin] "+c" (spin) - , [tmp] "=&r" (tmp) - : [holder] "m" (lock->holder) - : "cc" - ); -#elif defined(__ppc__) || defined(__PPC__) - __asm__ __volatile__ ( - "1: nop \n" - " nop \n" - " lwzx %[tmp], 0, %[holder] \n" - " cmpwi %[tmp], 0 \n" - " bdnzt eq, 1b \n" - : [spin] "+c" (spin) - , [tmp] "=&r" (tmp) - : [holder] "r" (&lock->holder) - : "cr0" - ); -#elif defined(__ppc64__) || defined(__PPC64__) - __asm__ __volatile__ ( - "1: nop \n" - " nop \n" - " ldx %[tmp], 0, %[holder] \n" - " cmpdi %[tmp], 0 \n" - " bdnzt eq, 1b \n" - : [spin] "+c" (spin) - , [tmp] "=&r" (tmp) - : [holder] "r" (&lock->holder) - : "cr0" - ); -#else - while (--spin > 0 && lock->holder != NULL) - osd_yield_processor(); -#endif -#if 0 - /* If you mean to use locks as a blocking mechanism for extended - * periods of time, you should do something like this. However, - * it kills the performance of gaelco3d. - */ - if (spin == 0) - { - struct timespec sleep = { 0, 100000 }, remaining; - nanosleep(&sleep, &remaining); // sleep for 100us - } -#endif - } while (osd_compare_exchange_pthread_t(&lock->holder, 0, current) != nullptr); - } - lock->count++; -} - -//============================================================ -// osd_lock_try -//============================================================ - -int osd_lock_try(osd_lock *lock) -{ - pthread_t current, prev; - - current = pthread_self(); - prev = osd_compare_exchange_pthread_t(&lock->holder, 0, current); - if (prev == nullptr || prev == current) - { - lock->count++; - return 1; - } - return 0; -} - -//============================================================ -// osd_lock_release -//============================================================ - -void osd_lock_release(osd_lock *lock) -{ - pthread_t current; - - current = pthread_self(); - if (lock->holder == current) - { - if (--lock->count == 0) -#if defined(__ppc__) || defined(__PPC__) || defined(__ppc64__) || defined(__PPC64__) - lock->holder = 0; - __asm__ __volatile__( " lwsync " : : ); -#else - osd_exchange_pthread_t(&lock->holder, 0); -#endif - return; - } - - // trying to release a lock you don't hold is bad! -// assert(lock->holder == pthread_self()); -} - -//============================================================ -// osd_lock_free -//============================================================ - -void osd_lock_free(osd_lock *lock) -{ - free(lock); -} - //============================================================ // osd_event_alloc //============================================================ |