Page MenuHomeFreeBSD

D22989.id.diff
No OneTemporary

D22989.id.diff

Index: sys/mips/include/atomic.h
===================================================================
--- sys/mips/include/atomic.h
+++ sys/mips/include/atomic.h
@@ -36,6 +36,17 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
+#if defined(__mips_o32) && defined(_KERNEL)
+#ifdef SMP
+#error MIPS O32 SMP is no longer supported.
+#endif
+
+#define _MIPS32_64BIT_ATOMICS
+#endif
+
+#ifdef _MIPS32_64BIT_ATOMICS
+#include <machine/cpufunc.h>
+#endif
#include <sys/atomic_common.h>
/*
@@ -52,6 +63,16 @@
#define __MIPS_PLATFORM_SYNC_NOPS ""
#endif
+#ifdef _MIPS32_64BIT_ATOMICS
+#define __with_interrupts_disabled(expr) \
+ do { \
+ register_t s; \
+ s = intr_disable(); \
+ (expr); \
+ intr_restore(s); \
+ } while(0)
+#endif
+
static __inline void
mips_sync(void)
{
@@ -284,7 +305,88 @@
return result;
}
-#endif
+#elif defined(_MIPS32_64BIT_ATOMICS)
+static __inline void
+atomic_set_64(volatile uint64_t *address, uint64_t setmask)
+{
+ __with_interrupts_disabled(*address |= setmask);
+}
+
+static __inline void
+atomic_clear_64(volatile uint64_t *address, uint64_t clearmask)
+{
+ __with_interrupts_disabled(*address &= ~clearmask);
+}
+
+static __inline uint64_t
+atomic_load_64(volatile uint64_t *p)
+{
+ uint64_t value;
+
+ __with_interrupts_disabled(value = *p);
+
+ return (value);
+}
+
+static __inline void
+atomic_store_64(volatile uint64_t *p, uint64_t value)
+{
+ __with_interrupts_disabled(*p = value);
+}
+
+static __inline void
+atomic_add_64(volatile u_int64_t *p, u_int64_t val)
+{
+ __with_interrupts_disabled(*p += val);
+}
+
+static __inline void
+atomic_subtract_64(volatile u_int64_t *p, u_int64_t val)
+{
+ __with_interrupts_disabled(*p -= val);
+}
+
+static __inline uint64_t
+atomic_swap_64(volatile uint64_t *p, uint64_t v)
+{
+ uint64_t value;
+
+ __with_interrupts_disabled(
+ {
+ value = *p;
+ *p = v;
+ });
+ return (value);
+}
+
+static __inline uint64_t
+atomic_readandclear_64(__volatile uint64_t *addr)
+{
+ uint64_t result;
+
+ __with_interrupts_disabled(
+ {
+ result = *addr;
+ *addr = 0;
+ });
+
+ return (result);
+}
+
+static __inline uint64_t
+atomic_readandset_64(__volatile uint64_t *addr, uint64_t value)
+{
+ uint64_t result;
+
+ __with_interrupts_disabled(
+ {
+ result = *addr;
+ *addr = value;
+ });
+
+ return (result);
+}
+#endif /* defined(__mips_n64) || defined(__mips_n32) */
#define ATOMIC_ACQ_REL(NAME, WIDTH) \
static __inline void \
@@ -314,7 +416,7 @@
ATOMIC_ACQ_REL(clear, 32)
ATOMIC_ACQ_REL(add, 32)
ATOMIC_ACQ_REL(subtract, 32)
-#if defined(__mips_n64) || defined(__mips_n32)
+#if defined(__mips_n64) || defined(__mips_n32) || defined(_MIPS32_64BIT_ATOMICS)
ATOMIC_ACQ_REL(set, 64)
ATOMIC_ACQ_REL(clear, 64)
ATOMIC_ACQ_REL(add, 64)
@@ -460,18 +562,6 @@
return (atomic_fcmpset_##WIDTH(p, cmpval, newval)); \
}
-/*
- * Atomically compare the value stored at *p with cmpval and if the
- * two values are equal, update the value of *p with newval. Returns
- * zero if the compare failed, nonzero otherwise.
- */
-ATOMIC_CMPSET_ACQ_REL(8);
-ATOMIC_CMPSET_ACQ_REL(16);
-ATOMIC_CMPSET_ACQ_REL(32);
-ATOMIC_FCMPSET_ACQ_REL(8);
-ATOMIC_FCMPSET_ACQ_REL(16);
-ATOMIC_FCMPSET_ACQ_REL(32);
-
/*
* Atomically add the value of v to the integer pointed to by p and return
* the previous value of *p.
@@ -543,14 +633,6 @@
return ret;
}
-/*
- * Atomically compare the value stored at *p with cmpval and if the
- * two values are equal, update the value of *p with newval. Returns
- * zero if the compare failed, nonzero otherwise.
- */
-ATOMIC_CMPSET_ACQ_REL(64);
-ATOMIC_FCMPSET_ACQ_REL(64);
-
/*
* Atomically add the value of v to the integer pointed to by p and return
* the previous value of *p.
@@ -570,6 +652,70 @@
: "r" (v), "m" (*p));
return (value);
}
+#elif defined(_MIPS32_64BIT_ATOMICS)
+static __inline int
+atomic_cmpset_64(__volatile uint64_t *p, uint64_t cmpval, uint64_t newval)
+{
+ int ret;
+
+ __with_interrupts_disabled(
+ {
+ if (*p == cmpval) {
+ *p = newval;
+ ret = 1;
+ } else {
+ ret = 0;
+ }
+ });
+ return (ret);
+}
+
+static __inline int
+atomic_fcmpset_64(__volatile uint64_t *p, uint64_t *cmpval, uint64_t newval)
+{
+ int ret;
+
+ __with_interrupts_disabled(
+ {
+ if (*p == *cmpval) {
+ *p = newval;
+ ret = 1;
+ } else {
+ *cmpval = *p;
+ ret = 0;
+ }
+ });
+ return (ret);
+}
+
+static __inline uint64_t
+atomic_fetchadd_64(volatile uint64_t *p, uint64_t v)
+{
+ uint64_t value;
+
+ __with_interrupts_disabled(
+ {
+ value = *p;
+ *p += v;
+ });
+ return (value);
+}
+#endif
+
+/*
+ * Atomically compare the value stored at *p with cmpval and if the
+ * two values are equal, update the value of *p with newval. Returns
+ * zero if the compare failed, nonzero otherwise.
+ */
+ATOMIC_CMPSET_ACQ_REL(8);
+ATOMIC_CMPSET_ACQ_REL(16);
+ATOMIC_CMPSET_ACQ_REL(32);
+ATOMIC_FCMPSET_ACQ_REL(8);
+ATOMIC_FCMPSET_ACQ_REL(16);
+ATOMIC_FCMPSET_ACQ_REL(32);
+#if defined(__mips_n64) || defined(__mips_n32) || defined(_MIPS32_64BIT_ATOMICS)
+ATOMIC_CMPSET_ACQ_REL(64);
+ATOMIC_FCMPSET_ACQ_REL(64);
#endif
static __inline void
@@ -844,4 +990,7 @@
#include <sys/_atomic_subword.h>
+#undef __with_interrupts_disabled
+#undef _MIPS32_64BIT_ATOMICS
+
#endif /* ! _MACHINE_ATOMIC_H_ */

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 12:14 AM (12 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31003371
Default Alt Text
D22989.id.diff (5 KB)

Event Timeline