From 433526a1232945257363f86e00cb1f6f4179cfa4 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 13 Jan 2003 22:14:20 +0000 Subject: [PATCH] Remove some x86-specific asm in the BSD DRM. For versions without an atomic_cmpset, use spls. --- bsd-core/drm_lock.c | 22 ++++++++-------------- bsd-core/drm_os_freebsd.h | 31 +++++++++++++++++-------------- bsd-core/drm_os_netbsd.h | 28 ++++++++++++++-------------- bsd/drm_lock.h | 22 ++++++++-------------- bsd/drm_os_freebsd.h | 31 +++++++++++++++++-------------- bsd/drm_os_netbsd.h | 28 ++++++++++++++-------------- 6 files changed, 78 insertions(+), 84 deletions(-) diff --git a/bsd-core/drm_lock.c b/bsd-core/drm_lock.c index 5e9294bc..bb99d9e6 100644 --- a/bsd-core/drm_lock.c +++ b/bsd-core/drm_lock.c @@ -47,14 +47,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - do { old = *lock; if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; else new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -77,14 +75,13 @@ int DRM(lock_transfer)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; dev->lock.pid = 0; do { old = *lock; new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + return 1; } @@ -93,14 +90,13 @@ int DRM(lock_free)(drm_device_t *dev, { unsigned int old, new; pid_t pid = dev->lock.pid; - char failed; dev->lock.pid = 0; do { old = *lock; new = 0; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", context, @@ -224,8 +220,6 @@ int DRM(notifier)(void *priv) { drm_sigdata_t *s = (drm_sigdata_t *)priv; unsigned int old, new; - char failed; - /* Allow signal delivery if lock isn't held */ if (!_DRM_LOCK_IS_HELD(s->lock->lock) @@ -236,8 +230,8 @@ int DRM(notifier)(void *priv) do { old = s->lock->lock; new = old | _DRM_LOCK_CONT; - _DRM_CAS(&s->lock->lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(&s->lock->lock, old, new)); + return 0; } diff --git a/bsd-core/drm_os_freebsd.h b/bsd-core/drm_os_freebsd.h index 00f5c434..c2b8cd5f 100644 --- a/bsd-core/drm_os_freebsd.h +++ b/bsd-core/drm_os_freebsd.h @@ -220,6 +220,23 @@ typedef u_int8_t u8; #define atomic_sub(n, p) atomic_subtract_int(p, n) /* Fake this */ + +#if __FreeBSD_version < 500000 +/* The extra atomic functions from 5.0 haven't been merged to 4.x */ +static __inline int +atomic_cmpset_int(int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} +#endif + static __inline atomic_t test_and_set_bit(int b, volatile void *p) { @@ -281,20 +298,6 @@ find_first_zero_bit(volatile void *p, int max) #endif -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void diff --git a/bsd-core/drm_os_netbsd.h b/bsd-core/drm_os_netbsd.h index 07704afd..44aa221a 100644 --- a/bsd-core/drm_os_netbsd.h +++ b/bsd-core/drm_os_netbsd.h @@ -170,6 +170,20 @@ typedef vaddr_t vm_offset_t; #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -219,20 +233,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void diff --git a/bsd/drm_lock.h b/bsd/drm_lock.h index 5e9294bc..bb99d9e6 100644 --- a/bsd/drm_lock.h +++ b/bsd/drm_lock.h @@ -47,14 +47,12 @@ int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; - do { old = *lock; if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT; else new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCKING_CONTEXT(old) == context) { if (old & _DRM_LOCK_HELD) { if (context != DRM_KERNEL_CONTEXT) { @@ -77,14 +75,13 @@ int DRM(lock_transfer)(drm_device_t *dev, __volatile__ unsigned int *lock, unsigned int context) { unsigned int old, new; - char failed; dev->lock.pid = 0; do { old = *lock; new = context | _DRM_LOCK_HELD; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + return 1; } @@ -93,14 +90,13 @@ int DRM(lock_free)(drm_device_t *dev, { unsigned int old, new; pid_t pid = dev->lock.pid; - char failed; dev->lock.pid = 0; do { old = *lock; new = 0; - _DRM_CAS(lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(lock, old, new)); + if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) { DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n", context, @@ -224,8 +220,6 @@ int DRM(notifier)(void *priv) { drm_sigdata_t *s = (drm_sigdata_t *)priv; unsigned int old, new; - char failed; - /* Allow signal delivery if lock isn't held */ if (!_DRM_LOCK_IS_HELD(s->lock->lock) @@ -236,8 +230,8 @@ int DRM(notifier)(void *priv) do { old = s->lock->lock; new = old | _DRM_LOCK_CONT; - _DRM_CAS(&s->lock->lock, old, new, failed); - } while (failed); + } while (!atomic_cmpset_int(&s->lock->lock, old, new)); + return 0; } diff --git a/bsd/drm_os_freebsd.h b/bsd/drm_os_freebsd.h index 00f5c434..c2b8cd5f 100644 --- a/bsd/drm_os_freebsd.h +++ b/bsd/drm_os_freebsd.h @@ -220,6 +220,23 @@ typedef u_int8_t u8; #define atomic_sub(n, p) atomic_subtract_int(p, n) /* Fake this */ + +#if __FreeBSD_version < 500000 +/* The extra atomic functions from 5.0 haven't been merged to 4.x */ +static __inline int +atomic_cmpset_int(int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} +#endif + static __inline atomic_t test_and_set_bit(int b, volatile void *p) { @@ -281,20 +298,6 @@ find_first_zero_bit(volatile void *p, int max) #endif -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void diff --git a/bsd/drm_os_netbsd.h b/bsd/drm_os_netbsd.h index 07704afd..44aa221a 100644 --- a/bsd/drm_os_netbsd.h +++ b/bsd/drm_os_netbsd.h @@ -170,6 +170,20 @@ typedef vaddr_t vm_offset_t; #define atomic_clear_int(p, bits) *(p) &= ~(bits) /* Fake this */ + +static __inline int +atomic_cmpset_int(int *dst, int old, int new) +{ + int s = splhigh(); + if (*dst==old) { + *dst = new; + splx(s); + return 1; + } + splx(s); + return 0; +} + static __inline atomic_t test_and_set_bit(int b, atomic_t *p) { @@ -219,20 +233,6 @@ find_first_zero_bit(atomic_t *p, int max) #define spldrm() spltty() #define jiffies hardclock_ticks -#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock) -#define _DRM_CAS(lock,old,new,__ret) \ - do { \ - int __dummy; /* Can't mark eax as clobbered */ \ - __asm__ __volatile__( \ - "lock ; cmpxchg %4,%1\n\t" \ - "setnz %0" \ - : "=d" (__ret), \ - "=m" (__drm_dummy_lock(lock)), \ - "=a" (__dummy) \ - : "2" (old), \ - "r" (new)); \ - } while (0) - /* Redefinitions to make templating easy */ #define wait_queue_head_t atomic_t #define agp_memory void