diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-02 21:21:31 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-02 21:21:31 +0000 |
commit | 1650e61219b0f085938ffd3529b18f122e371efd (patch) | |
tree | 872abb896c319c905210f0d4c4a335069a857a7f /sys/arch | |
parent | 9ddcf1d8e7bdf80e4736afe986c5f0d16cb79111 (diff) |
Provide a specific rw_cas() function for MP kernels, simulating a really
atomic compare-and-swap operation.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/m88k/include/lock.h | 7 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/m88k_machdep.c | 33 |
2 files changed, 38 insertions, 2 deletions
diff --git a/sys/arch/m88k/include/lock.h b/sys/arch/m88k/include/lock.h index 13bfc2d0960..06eebcfaf2d 100644 --- a/sys/arch/m88k/include/lock.h +++ b/sys/arch/m88k/include/lock.h @@ -1,6 +1,6 @@ #ifndef _M88K_LOCK_H_ #define _M88K_LOCK_H_ -/* $OpenBSD: lock.h,v 1.5 2007/10/27 20:36:17 miod Exp $ */ +/* $OpenBSD: lock.h,v 1.6 2007/12/02 21:21:29 miod Exp $ */ /* * Copyright (c) 2005, Miodrag Vallat. @@ -81,4 +81,9 @@ __cpu_simple_unlock(__cpu_simple_lock_t *l) *l = __SIMPLELOCK_UNLOCKED; } +#if defined(_KERNEL) && defined(MULTIPROCESSOR) +int rw_cas_m88k(volatile unsigned long *, unsigned long, unsigned long); +#define rw_cas rw_cas_m88k +#endif + #endif /* _M88K_LOCK_H_ */ diff --git a/sys/arch/m88k/m88k/m88k_machdep.c b/sys/arch/m88k/m88k/m88k_machdep.c index cf81fd6ad1e..1044d2e7f2a 100644 --- a/sys/arch/m88k/m88k/m88k_machdep.c +++ b/sys/arch/m88k/m88k/m88k_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: m88k_machdep.c,v 1.34 2007/11/22 05:42:50 miod Exp $ */ +/* $OpenBSD: m88k_machdep.c,v 1.35 2007/12/02 21:21:30 miod Exp $ */ /* * Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr. * Copyright (c) 1996 Nivas Madhur @@ -502,4 +502,35 @@ cpu_emergency_disable() /* NOTREACHED */ } +/* + * Emulate a compare-and-swap instruction for rwlocks, by using a + * __cpu_simple_lock as a critical section. + * + * Since we are only competing against other processors for rwlocks, + * it is not necessary in this case to disable interrupts to prevent + * reentrancy on the same processor. + * + * Updates need to be done with xmem to ensure they are atomic. + */ + +__cpu_simple_lock_t rw_cas_spinlock = __SIMPLELOCK_UNLOCKED; + +int +rw_cas_m88k(volatile unsigned long *p, unsigned long o, unsigned long n) +{ + int rc = 0; + + __cpu_simple_lock(&rw_cas_spinlock); + + if (*p != o) + rc = 1; + /* atomic *p = n; */ + __asm__ __volatile__ + ("xmem %0, %2, r0" : "+r"(n), "+m"(*p) : "r"(p)); + + __cpu_simple_unlock(&rw_cas_spinlock); + + return (rc); +} + #endif /* MULTIPROCESSOR */ |