Remove some x86-specific asm in the BSD DRM. For versions without an

atomic_cmpset, use spls.
This commit is contained in:
Eric Anholt 2003-01-13 22:14:20 +00:00
parent b3b6c102ee
commit 433526a123
6 changed files with 78 additions and 84 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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