aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64/include
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2023-07-07 20:06:55 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2023-07-07 20:06:55 +0000
commit2329393c615cf61c19b0d7bd1ca18663e02789ce (patch)
tree078854416c50456a55f0bffe506e91e868bf6a38 /sys/amd64/include
parent1f7e3572644ef46c27439c89ab1bb09d140dc30e (diff)
Diffstat (limited to 'sys/amd64/include')
-rw-r--r--sys/amd64/include/pcpu.h69
1 files changed, 63 insertions, 6 deletions
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index 523cf105e1c7..dc78a07b83e9 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -114,17 +114,73 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
#define MONITOR_STOPSTATE_STOPPED 1
/*
- * Evaluates to the byte offset of the per-cpu variable name.
- */
-#define __pcpu_offset(name) \
- __offsetof(struct pcpu, name)
-
-/*
* Evaluates to the type of the per-cpu variable name.
*/
#define __pcpu_type(name) \
__typeof(((struct pcpu *)0)->name)
+#ifdef __SEG_GS
+#define get_pcpu() __extension__ ({ \
+ static struct pcpu __seg_gs *__pc = 0; \
+ \
+ __pc->pc_prvspace; \
+})
+
+/*
+ * Evaluates to the address of the per-cpu variable name.
+ */
+#define __PCPU_PTR(name) __extension__ ({ \
+ struct pcpu *__pc = get_pcpu(); \
+ \
+ &__pc->name; \
+})
+
+/*
+ * Evaluates to the value of the per-cpu variable name.
+ */
+#define __PCPU_GET(name) __extension__ ({ \
+ static struct pcpu __seg_gs *__pc = 0; \
+ \
+ __pc->name; \
+})
+
+/*
+ * Adds the value to the per-cpu counter name. The implementation
+ * must be atomic with respect to interrupts.
+ */
+#define __PCPU_ADD(name, val) do { \
+ static struct pcpu __seg_gs *__pc = 0; \
+ __pcpu_type(name) __val; \
+ \
+ __val = (val); \
+ if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
+ sizeof(__val) == 4 || sizeof(__val) == 8) { \
+ __pc->name += __val; \
+ } else \
+ *__PCPU_PTR(name) += __val; \
+} while (0)
+
+/*
+ * Sets the value of the per-cpu variable name to value val.
+ */
+#define __PCPU_SET(name, val) { \
+ static struct pcpu __seg_gs *__pc = 0; \
+ __pcpu_type(name) __val; \
+ \
+ __val = (val); \
+ if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
+ sizeof(__val) == 4 || sizeof(__val) == 8) { \
+ __pc->name = __val; \
+ } else \
+ *__PCPU_PTR(name) = __val; \
+} while (0)
+#else /* !__SEG_GS */
+/*
+ * Evaluates to the byte offset of the per-cpu variable name.
+ */
+#define __pcpu_offset(name) \
+ __offsetof(struct pcpu, name)
+
/*
* Evaluates to the address of the per-cpu variable name.
*/
@@ -210,6 +266,7 @@ _Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
: "m" (*(struct pcpu *)(__pcpu_offset(pc_prvspace)))); \
__pc; \
})
+#endif /* !__SEG_GS */
#define PCPU_GET(member) __PCPU_GET(pc_ ## member)
#define PCPU_ADD(member, val) __PCPU_ADD(pc_ ## member, val)