tech-userlevel archive

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

atomic read in atomic_ops(9)



Hi lists,

I encounter situations where I'd like to read a 64 bits value atomically under a 32 bits platform (canonical example is Xen balloon(4)), yet the current atomic_ops(9) functions do not provide a stub for it.

In fact it does, somewhat; if you use "atomic_cas_64(ptr, 0, 0)". Eww.

Would it be acceptable to add a simple function for this (see attached example)? That allows reading uint64_t and "long long" variables atomically.

I assume that all aligned reads with a size equal to native word size are atomic for all the platforms we support, so I am leaving out all the atomic_read_32/long() functions (do they make any sense anyway?). I have to provide the function for 64 bits architectures for completeness.

Opinions? If acceptable, I can add the function to other architectures too.

Happy holidays!

--
Jean-Yves Migeon
Index: common/lib/libc/arch/i386/atomic/Makefile.inc
===================================================================
RCS file: /cvsroot/src/common/lib/libc/arch/i386/atomic/Makefile.inc,v
retrieving revision 1.7
diff -u -p -r1.7 Makefile.inc
--- common/lib/libc/arch/i386/atomic/Makefile.inc       4 Jan 2009 17:54:29 
-0000       1.7
+++ common/lib/libc/arch/i386/atomic/Makefile.inc       25 Dec 2011 23:39:02 
-0000
@@ -6,7 +6,8 @@
 SRCS+= atomic_add_64_cas.c atomic_add_64_nv_cas.c atomic_and_64_cas.c \
        atomic_and_64_nv_cas.c atomic_dec_64_cas.c atomic_dec_64_nv_cas.c \
        atomic_inc_64_cas.c atomic_inc_64_nv_cas.c atomic_or_64_cas.c \
-       atomic_or_64_nv_cas.c atomic_swap_64_cas.c atomic.S
+       atomic_or_64_nv_cas.c atomic_read_64_cas.c \
+       atomic_swap_64_cas.c atomic.S
 
 .endif
 
Index: common/lib/libc/arch/x86_64/atomic/atomic.S
===================================================================
RCS file: /cvsroot/src/common/lib/libc/arch/x86_64/atomic/atomic.S,v
retrieving revision 1.16
diff -u -p -r1.16 atomic.S
--- common/lib/libc/arch/x86_64/atomic/atomic.S 12 Jan 2011 23:12:10 -0000      
1.16
+++ common/lib/libc/arch/x86_64/atomic/atomic.S 25 Dec 2011 23:39:03 -0000
@@ -206,6 +206,11 @@ ENTRY(_atomic_or_64_nv)
        movq    %rcx, %rax
        ret
 
+ENTRY(_atomic_read_64)
+       LOCK(23)
+       movq    (%rdi), %rax
+       ret
+
 ENTRY(_atomic_swap_64)
        movq    %rsi, %rax
        xchgq   %rax, (%rdi)
@@ -261,7 +266,7 @@ atomic_lockpatch:
        .quad   .Lpatch6, .Lpatch7, .Lpatch8, .Lpatch9, .Lpatch10
        .quad   .Lpatch12, .Lpatch13, .Lpatch14, .Lpatch15
        .quad   .Lpatch16, .Lpatch17, .Lpatch18, .Lpatch19, .Lpatch20
-       .quad   .Lpatch21, .Lpatch22, .Lpatch24, .Lpatch25
+       .quad   .Lpatch21, .Lpatch22, .Lpatch23, .Lpatch24, .Lpatch25
        .quad   .Lpatch26, 0
 #endif /* _HARDKERNEL */
 
@@ -324,6 +329,8 @@ ALIAS(atomic_or_uint_nv,_atomic_or_32_nv
 ALIAS(atomic_or_ulong_nv,_atomic_or_64_nv)
 ALIAS(atomic_or_ptr_nv,_atomic_or_64_nv)
 
+ALIAS(atomic_read_64,_atomic_read_64)
+
 ALIAS(atomic_swap_32,_atomic_swap_32)
 ALIAS(atomic_swap_64,_atomic_swap_64)
 ALIAS(atomic_swap_uint,_atomic_swap_32)
Index: common/lib/libc/atomic/atomic_op_namespace.h
===================================================================
RCS file: /cvsroot/src/common/lib/libc/atomic/atomic_op_namespace.h,v
retrieving revision 1.4
diff -u -p -r1.4 atomic_op_namespace.h
--- common/lib/libc/atomic/atomic_op_namespace.h        23 Jun 2008 10:33:52 
-0000      1.4
+++ common/lib/libc/atomic/atomic_op_namespace.h        25 Dec 2011 23:39:03 
-0000
@@ -80,6 +80,8 @@
 #define        atomic_cas_ptr_ni       _atomic_cas_ptr_ni
 #define        atomic_cas_64_ni        _atomic_cas_64_ni
 
+#define        atomic_read_64          _atomic_read_64
+
 #define        atomic_swap_32          _atomic_swap_32
 #define        atomic_swap_uint        _atomic_swap_uint
 #define        atomic_swap_ulong       _atomic_swap_ulong
--- /dev/null   2011-12-25 23:16:50.000000000 +0100
+++ common/lib/libc/atomic/atomic_read_64_cas.c 2011-12-26 00:25:05.000000000 
+0100
@@ -0,0 +1,48 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jean-Yves Migeon.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "atomic_op_namespace.h"
+
+#include <sys/atomic.h>
+
+#ifdef __HAVE_ATOMIC64_OPS
+
+uint64_t
+atomic_read_64(volatile uint64_t *addr)
+{
+
+       return atomic_cas_64(addr, 0, 0);
+}
+
+#undef atomic_read_64
+atomic_op_alias(atomic_read_64,_atomic_read_64)
+
+#endif


Home | Main Index | Thread Index | Old Index