Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/common/lib/libc/atomic Provide CAS variants for 16 and 8 bit...



details:   https://anonhg.NetBSD.org/src/rev/e2471e8e0ee7
branches:  trunk
changeset: 326981:e2471e8e0ee7
user:      martin <martin%NetBSD.org@localhost>
date:      Mon Feb 24 17:18:27 2014 +0000

description:
Provide CAS variants for 16 and 8 bit when running with more that 1 cpu

diffstat:

 common/lib/libc/atomic/atomic_init_testset.c |  48 ++++++++++++++++++++++++++-
 1 files changed, 45 insertions(+), 3 deletions(-)

diffs (83 lines):

diff -r 903ffd72fbeb -r e2471e8e0ee7 common/lib/libc/atomic/atomic_init_testset.c
--- a/common/lib/libc/atomic/atomic_init_testset.c      Mon Feb 24 16:57:57 2014 +0000
+++ b/common/lib/libc/atomic/atomic_init_testset.c      Mon Feb 24 17:18:27 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atomic_init_testset.c,v 1.13 2014/02/22 17:08:30 martin Exp $  */
+/*     $NetBSD: atomic_init_testset.c,v 1.14 2014/02/24 17:18:27 martin Exp $  */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: atomic_init_testset.c,v 1.13 2014/02/22 17:08:30 martin Exp $");
+__RCSID("$NetBSD: atomic_init_testset.c,v 1.14 2014/02/24 17:18:27 martin Exp $");
 
 #include "atomic_op_namespace.h"
 
@@ -53,6 +53,12 @@
 #define        I128    I16 I16 I16 I16 I16 I16 I16 I16
 
 static __cpu_simple_lock_t atomic_locks[128] = { I128 };
+/*
+ * Pick a lock out of above array depending on the object address
+ * passed. Most variables used atomically will not be in the same
+ * cacheline - and if they are, using the same lock is fine.
+ */
+#define HASH(PTR)      (((uintptr_t)(PTR) >> 3) & 127)
 
 #ifdef __HAVE_ASM_ATOMIC_CAS_UP
 extern uint32_t _atomic_cas_up(volatile uint32_t *, uint32_t, uint32_t);
@@ -143,7 +149,41 @@
        __cpu_simple_lock_t *lock;
        uint32_t ret;
 
-       lock = &atomic_locks[((uintptr_t)ptr >> 3) & 127];
+       lock = &atomic_locks[HASH(ptr)];
+       __cpu_simple_lock(lock);
+       ret = *ptr;
+       if (__predict_true(ret == old)) {
+               *ptr = new;
+       }
+       __cpu_simple_unlock(lock);
+
+       return ret;
+}
+
+static uint16_t
+_atomic_cas_16_mp(volatile uint16_t *ptr, uint16_t old, uint16_t new)
+{
+       __cpu_simple_lock_t *lock;
+       uint16_t ret;
+
+       lock = &atomic_locks[HASH(ptr)];
+       __cpu_simple_lock(lock);
+       ret = *ptr;
+       if (__predict_true(ret == old)) {
+               *ptr = new;
+       }
+       __cpu_simple_unlock(lock);
+
+       return ret;
+}
+
+static uint8_t
+_atomic_cas_8_mp(volatile uint8_t *ptr, uint8_t old, uint8_t new)
+{
+       __cpu_simple_lock_t *lock;
+       uint8_t ret;
+
+       lock = &atomic_locks[HASH(ptr)];
        __cpu_simple_lock(lock);
        ret = *ptr;
        if (__predict_true(ret == old)) {
@@ -186,6 +226,8 @@
        size_t len;
 
        _atomic_cas_fn = _atomic_cas_mp;
+       _atomic_cas_16_fn = _atomic_cas_16_mp;
+       _atomic_cas_8_fn = _atomic_cas_8_mp;
 
        mib[0] = CTL_HW;
        mib[1] = HW_NCPU; 



Home | Main Index | Thread Index | Old Index