diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-27 00:08:28 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2009-11-27 00:08:28 +0000 |
commit | 195eb75588cdb8ec88ca9985c49402c1780706ba (patch) | |
tree | 0697d4ac521a096e16f1ff2e86992af4a555fa5c | |
parent | ff500d53e0a8255f083e6114a7be1b80083069d7 (diff) |
atomic counter increment for SMP.
ok jsing@
-rw-r--r-- | sys/arch/mips64/include/atomic.h | 30 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/interrupt.c | 6 | ||||
-rw-r--r-- | sys/arch/sgi/sgi/intr_template.c | 4 |
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; |