Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151095097
D22989.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D22989.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D22989: mips o32: provide 64-bit atomics
Attached
Detach File
Event Timeline
Log In to Comment