summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2007-06-04 21:38:48 +0000
committerattilio <attilio@FreeBSD.org>2007-06-04 21:38:48 +0000
commite333d0ff0eb23a5f94f36fd95b4bbcfda3ccbc8f (patch)
treea35bbd71798a97fd11a5f264ff97c562de001111 /sys/amd64
parent771efb08f5bfaf22da0498ae91647fdecb3cc6bb (diff)
downloadFreeBSD-src-e333d0ff0eb23a5f94f36fd95b4bbcfda3ccbc8f.zip
FreeBSD-src-e333d0ff0eb23a5f94f36fd95b4bbcfda3ccbc8f.tar.gz
Rework the PCPU_* (MD) interface:
- Rename PCPU_LAZY_INC into PCPU_INC - Add the PCPU_ADD interface which just does an add on the pcpu member given a specific value. Note that for most architectures PCPU_INC and PCPU_ADD are not safe. This is a point that needs some discussions/work in the next days. Reviewed by: alc, bde Approved by: jeff (mentor)
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/intr_machdep.c4
-rw-r--r--sys/amd64/amd64/trap.c6
-rw-r--r--sys/amd64/ia32/ia32_syscall.c4
-rw-r--r--sys/amd64/include/pcpu.h29
4 files changed, 33 insertions, 10 deletions
diff --git a/sys/amd64/amd64/intr_machdep.c b/sys/amd64/amd64/intr_machdep.c
index 6ed8c80..3dc1361 100644
--- a/sys/amd64/amd64/intr_machdep.c
+++ b/sys/amd64/amd64/intr_machdep.c
@@ -250,7 +250,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
* processed too.
*/
(*isrc->is_count)++;
- PCPU_LAZY_INC(cnt.v_intr);
+ PCPU_INC(cnt.v_intr);
ie = isrc->is_event;
@@ -321,7 +321,7 @@ intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
* processed too.
*/
(*isrc->is_count)++;
- PCPU_LAZY_INC(cnt.v_intr);
+ PCPU_INC(cnt.v_intr);
ie = isrc->is_event;
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 23a30cc8..4bdaa73 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -163,7 +163,7 @@ trap(struct trapframe *frame)
register_t addr = 0;
ksiginfo_t ksi;
- PCPU_LAZY_INC(cnt.v_trap);
+ PCPU_INC(cnt.v_trap);
type = frame->tf_trapno;
#ifdef SMP
@@ -737,10 +737,10 @@ syscall(struct trapframe *frame)
ksiginfo_t ksi;
/*
- * note: PCPU_LAZY_INC() can only be used if we can afford
+ * note: PCPU_INC() can only be used if we can afford
* occassional inaccuracy in the count.
*/
- PCPU_LAZY_INC(cnt.v_syscall);
+ PCPU_INC(cnt.v_syscall);
#ifdef DIAGNOSTIC
if (ISPL(frame->tf_cs) != SEL_UPL) {
diff --git a/sys/amd64/ia32/ia32_syscall.c b/sys/amd64/ia32/ia32_syscall.c
index c51a2be..40ec2e6 100644
--- a/sys/amd64/ia32/ia32_syscall.c
+++ b/sys/amd64/ia32/ia32_syscall.c
@@ -105,10 +105,10 @@ ia32_syscall(struct trapframe *frame)
ksiginfo_t ksi;
/*
- * note: PCPU_LAZY_INC() can only be used if we can afford
+ * note: PCPU_INC() can only be used if we can afford
* occassional inaccuracy in the count.
*/
- PCPU_LAZY_INC(cnt.v_syscall);
+ PCPU_INC(cnt.v_syscall);
td->td_pticks = 0;
td->td_frame = frame;
diff --git a/sys/amd64/include/pcpu.h b/sys/amd64/include/pcpu.h
index 47d9b0e..9245bbe 100644
--- a/sys/amd64/include/pcpu.h
+++ b/sys/amd64/include/pcpu.h
@@ -56,7 +56,8 @@
extern struct pcpu *pcpup;
#define PCPU_GET(member) (pcpup->pc_ ## member)
-#define PCPU_LAZY_INC(member) (++pcpup->pc_ ## member)
+#define PCPU_ADD(member, val) (pcpup->pc_ ## member += (val))
+#define PCPU_INC(member) PCPU_ADD(member, 1)
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
#define PCPU_SET(member, val) (pcpup->pc_ ## member = (val))
@@ -110,10 +111,31 @@ extern struct pcpu *pcpup;
})
/*
+ * Adds the value to the per-cpu counter name. The implementation
+ * must be atomic with respect to interrupts.
+ */
+#define __PCPU_ADD(name, val) do { \
+ __pcpu_type(name) __val; \
+ struct __s { \
+ u_char __b[MIN(sizeof(__pcpu_type(name)), 8)]; \
+ } __s; \
+ \
+ __val = (val); \
+ if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
+ sizeof(__val) == 4 || sizeof(__val) == 8) { \
+ __s = *(struct __s *)(void *)&__val; \
+ __asm __volatile("add %1,%%gs:%0" \
+ : "=m" (*(struct __s *)(__pcpu_offset(name))) \
+ : "r" (__s)); \
+ } else \
+ *__PCPU_PTR(name) += __val; \
+} while (0)
+
+/*
* Increments the value of the per-cpu counter name. The implementation
* must be atomic with respect to interrupts.
*/
-#define __PCPU_LAZY_INC(name) do { \
+#define __PCPU_INC(name) do { \
CTASSERT(sizeof(__pcpu_type(name)) == 1 || \
sizeof(__pcpu_type(name)) == 2 || \
sizeof(__pcpu_type(name)) == 4 || \
@@ -159,7 +181,8 @@ extern struct pcpu *pcpup;
}
#define PCPU_GET(member) __PCPU_GET(pc_ ## member)
-#define PCPU_LAZY_INC(member) __PCPU_LAZY_INC(pc_ ## member)
+#define PCPU_ADD(member, val) __PCPU_ADD(pc_ ## member, val)
+#define PCPU_INC(member) __PCPU_INC(pc_ ## member)
#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member)
#define PCPU_SET(member, val) __PCPU_SET(pc_ ## member, val)
OpenPOWER on IntegriCloud