summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2009-11-27 00:08:28 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2009-11-27 00:08:28 +0000
commit195eb75588cdb8ec88ca9985c49402c1780706ba (patch)
tree0697d4ac521a096e16f1ff2e86992af4a555fa5c
parentff500d53e0a8255f083e6114a7be1b80083069d7 (diff)
atomic counter increment for SMP.
ok jsing@
-rw-r--r--sys/arch/mips64/include/atomic.h30
-rw-r--r--sys/arch/mips64/mips64/interrupt.c6
-rw-r--r--sys/arch/sgi/sgi/intr_template.c4
3 files changed, 34 insertions, 6 deletions
diff --git a/sys/arch/mips64/include/atomic.h b/sys/arch/mips64/include/atomic.h
index 0c6789e465a..ea4a2a7f121 100644
--- a/sys/arch/mips64/include/atomic.h
+++ b/sys/arch/mips64/include/atomic.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomic.h,v 1.4 2009/04/12 17:52:17 miod Exp $ */
+/* $OpenBSD: atomic.h,v 1.5 2009/11/27 00:08:27 syuu Exp $ */
/* Public Domain */
@@ -37,5 +37,33 @@ atomic_clearbits_int(__volatile unsigned int *uip, unsigned int v)
"r"(uip), "r"(~v) : "memory");
}
+static __inline void
+atomic_add_int(__volatile unsigned int *uip, unsigned int v)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__ (
+ "1: ll %0, 0(%1)\n"
+ " addu %0, %2, %0\n"
+ " sc %0, 0(%1)\n"
+ " beqz %0, 1b\n"
+ " nop\n" :
+ "=&r"(tmp) :
+ "r"(uip), "r"(v) : "memory");
+}
+static __inline void
+atomic_add_uint64(__volatile uint64_t *uip, uint64_t v)
+{
+ uint64_t tmp;
+
+ __asm__ __volatile__ (
+ "1: lld %0, 0(%1)\n"
+ " daddu %0, %2, %0\n"
+ " scd %0, 0(%1)\n"
+ " beqz %0, 1b\n"
+ " nop\n" :
+ "=&r"(tmp) :
+ "r"(uip), "r"(v) : "memory");
+}
#endif /* defined(_KERNEL) */
#endif /* __MIPS64_ATOMIC_H__ */
diff --git a/sys/arch/mips64/mips64/interrupt.c b/sys/arch/mips64/mips64/interrupt.c
index 5bd47a08a4c..923fc8ff147 100644
--- a/sys/arch/mips64/mips64/interrupt.c
+++ b/sys/arch/mips64/mips64/interrupt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interrupt.c,v 1.54 2009/11/26 23:32:46 syuu Exp $ */
+/* $OpenBSD: interrupt.c,v 1.55 2009/11/27 00:08:27 syuu Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -114,14 +114,14 @@ interrupt(struct trap_frame *trapframe)
#ifdef DEBUG_INTERRUPT
trapdebug_enter(trapframe, 0);
#endif
- uvmexp.intrs++;
+ atomic_add_int(&uvmexp.intrs, 1);
/* Mask out interrupts from cause that are unmasked */
pending = trapframe->cause & CR_IPEND & trapframe->sr;
if (pending & SOFT_INT_MASK_0) {
clearsoftintr0();
- soft_count.ec_count++;
+ atomic_add_uint64(&soft_count.ec_count, 1);
}
#ifdef RM7K_PERFCNTR
diff --git a/sys/arch/sgi/sgi/intr_template.c b/sys/arch/sgi/sgi/intr_template.c
index 9880ab66998..2aedc63af6c 100644
--- a/sys/arch/sgi/sgi/intr_template.c
+++ b/sys/arch/sgi/sgi/intr_template.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr_template.c,v 1.6 2009/11/25 17:39:51 syuu Exp $ */
+/* $OpenBSD: intr_template.c,v 1.7 2009/11/27 00:08:27 syuu Exp $ */
/*
* Copyright (c) 2009 Miodrag Vallat.
@@ -156,7 +156,7 @@ INTR_FUNCTIONNAME(uint32_t hwpend, struct trap_frame *frame)
splraise(ih->ih_level);
if ((*ih->ih_fun)(ih->ih_arg) != 0) {
rc = 1;
- ih->ih_count.ec_count++;
+ atomic_add_uint64(&ih->ih_count.ec_count, 1);
}
__asm__ (".set noreorder\n");
ci->ci_ipl = ipl;