]> granicus.if.org Git - libatomic_ops/commitdiff
2007-06-06 Hans Boehm <Hans.Boehm@hp.com>
authorhboehm <hboehm>
Wed, 6 Jun 2007 19:54:12 +0000 (19:54 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 25 Jul 2011 12:03:24 +0000 (16:03 +0400)
* src/atomic_ops/sysdeps/msftc/x86_64.h: New file.
* src/atomic_ops.h: Add test for msftc/x86_64.h.
* src/atomic_ops/sysdeps/msftc/x86.h: Complain for _WIN64.
* src/atomic_ops/sysdeps/Makefile.am: Add x86_64.h.
* src/atomic_ops/sysdeps/Makefile.in: Regenerate.
* src/atomic_ops/sysdeps/aligned_atomic_load_store.h,
  src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h,
  src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h:
  Replace unsigned long cast with size_t.

ChangeLog
src/atomic_ops.h
src/atomic_ops/sysdeps/Makefile.am
src/atomic_ops/sysdeps/Makefile.in
src/atomic_ops/sysdeps/aligned_atomic_load_store.h
src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h
src/atomic_ops/sysdeps/msftc/x86.h
src/atomic_ops/sysdeps/msftc/x86_64.h [new file with mode: 0644]
src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h

index 8360f50858882ab384feddcc2c6ad8258e999adb..2e2af53806ed25021951f528d64e20b217796ba2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-06-06 Hans Boehm <Hans.Boehm@hp.com>
+       * src/atomic_ops/sysdeps/msftc/x86_64.h: New file.
+       * src/atomic_ops.h: Add test for msftc/x86_64.h.
+       * src/atomic_ops/sysdeps/msftc/x86.h: Complain for _WIN64.
+       * src/atomic_ops/sysdeps/Makefile.am: Add x86_64.h.
+       * src/atomic_ops/sysdeps/Makefile.in: Regenerate.
+       * src/atomic_ops/sysdeps/aligned_atomic_load_store.h,
+         src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h,
+         src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h:
+         Replace unsigned long cast with size_t.
+
 2007-05-17 Hans Boehm <Hans.Boehm@hp.com>
        * src/atomic_ops/sysdeps/gcc/hppa.h (AO_test_and_set_full):
        Add cast for return.
index c23f30bfa5019c341959a3944f65343ee1c23226..c0ee9830105bae87ff4d0b60a79cdea31c5f8fc5 100755 (executable)
 /* atomic_ops_generalize.h.                                    */
 
 /* Some common defaults.  Overridden for some architectures.   */
-#define AO_t unsigned long
-       /* Could conceivably be redefined below if/when we add  */
-       /* win64 support.                                       */
+#define AO_t size_t
 
 /* The test_and_set primitive returns an AO_TS_VAL_t value.    */
 /* AO_TS_t is the type of an in-memory test-and-set location.  */
 #if defined(__GNUC__) && !defined(__INTEL_COMPILER)
 # define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory")
 #elif defined(_MSC_VER)
-# define AO_compiler_barrier() __asm { }
+# if defined(_AMD64_)
+#   pragma intrinsic(_ReadWriteBarrier)
+#   define AO_compiler_barrier() _ReadWriteBarrier()
+       /* We assume this does not generate a fence instruction.        */
+       /* The documentation is a bit unclear.                          */
+# else
+#   define AO_compiler_barrier() __asm { }
+       /* The preceding implementation may be preferable here too.     */
+       /* But the documentation warns about VC++ 2003 and earlier.     */
+# endif
 #elif defined(__INTEL_COMPILER)
 # define AO_compiler_barrier() __memory_barrier() /* Too strong? IA64-only? */
 #elif defined(_HPUX_SOURCE)
 #endif
 
 #if defined(_MSC_VER)
-# if _M_IX86 >= 400
+# if defined(_AMD64_)
+#   include "atomic_ops/sysdeps/msftc/x86_64.h"
+# elif _M_IX86 >= 400
 #   include "atomic_ops/sysdeps/msftc/x86.h"
 # endif
 #endif
index 74122b48a1d5730cd36abe9cb3020adf04e36d75..8204d8d20c6817e7faf8166960294441fd6836c3 100644 (file)
@@ -33,6 +33,7 @@ nobase_sysdep_HEADERS= generic_pthread.h \
          icc/ia64.h \
        \
          msftc/x86.h \
+         msftc/x86_64.h \
        \
          hpc/ia64.h hpc/hppa.h \
        \
index 102d2e0da25c054a18be431205494178fe3dd8ef..e7daa7dc6de857277e506e73add6e0c3449a61ec 100644 (file)
@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004  Free Software Foundation, Inc.
+# 2003, 2004, 2005  Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -84,6 +84,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
@@ -110,8 +111,6 @@ SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
 ac_ct_CC = @ac_ct_CC@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
@@ -126,23 +125,30 @@ build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
 datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
 host_alias = @host_alias@
 host_cpu = @host_cpu@
 host_os = @host_os@
 host_vendor = @host_vendor@
+htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
+localedir = @localedir@
 localstatedir = @localstatedir@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
+psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
@@ -187,6 +193,7 @@ nobase_sysdep_HEADERS = generic_pthread.h \
          icc/ia64.h \
        \
          msftc/x86.h \
+         msftc/x86_64.h \
        \
          hpc/ia64.h hpc/hppa.h \
        \
index e69c0dd664b4bdcce474a0a49110b970af7c18dc..485b7f45a073a8e53f897c25c510b592890de154 100644 (file)
@@ -28,7 +28,7 @@
 AO_INLINE AO_t
 AO_load(volatile AO_t *addr)
 {
-  assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(AO_t) - 1)) == 0);
   /* Cast away the volatile for architectures where            */
   /* volatile adds barrier semantics.                          */
   return *(AO_t *)addr;
@@ -39,7 +39,7 @@ AO_load(volatile AO_t *addr)
 AO_INLINE void
 AO_store(volatile AO_t *addr, AO_t new_val)
 {
-  assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(AO_t) - 1)) == 0);
   (*(AO_t *)addr) = new_val;
 }
 
index fa5965624794e7b2dfdf1a8bcefb8b2563ac8310..62927d2e78ed150b6736ff789336a80ae0ca07ab 100644 (file)
@@ -28,7 +28,7 @@
 AO_INLINE unsigned int
 AO_int_load(volatile unsigned int *addr)
 {
-  assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(unsigned int) - 1)) == 0);
   /* Cast away the volatile for architectures like IA64 where  */
   /* volatile adds barrier semantics.                          */
   return (*(unsigned int *)addr);
@@ -39,7 +39,7 @@ AO_int_load(volatile unsigned int *addr)
 AO_INLINE void
 AO_int_store(volatile unsigned int *addr, unsigned int new_val)
 {
-  assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(unsigned int) - 1)) == 0);
   (*(unsigned int *)addr) = new_val;
 }
 
index 2376d0c205783866cfdeb6807479b7878e67c675..ad444580f1eeb645800e25e4eb58fd9cac6ea2be 100644 (file)
@@ -155,6 +155,8 @@ AO_compare_and_swap_full(volatile AO_t *addr,
 #define AO_HAVE_compare_and_swap_full
 #endif /* ASSUME_WINDOWS98 */
 
-#ifndef _WIN64
-#include "../ao_t_is_int.h"
+#ifdef _WIN64
+#  error wrong architecture
 #endif
+
+#include "../ao_t_is_int.h"
diff --git a/src/atomic_ops/sysdeps/msftc/x86_64.h b/src/atomic_ops/sysdeps/msftc/x86_64.h
new file mode 100644 (file)
index 0000000..7f0b647
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE. 
+ */
+
+/* The following really assume we have a 486 or better. */
+/* If ASSUME_WINDOWS98 is defined, we assume Windows 98 or newer.      */
+
+#include "../all_aligned_atomic_load_store.h"
+
+/* Real X86 implementations, except for some old WinChips, appear      */
+/* to enforce ordering between memory operations, EXCEPT that a later  */
+/* read can pass earlier writes, presumably due to the visible         */
+/* presence of store buffers.                                          */
+/* We ignore both the WinChips, and the fact that the official specs   */
+/* seem to be much weaker (and arguably too weak to be usable).                */
+
+#include "../ordered_except_wr.h"
+
+#if 0
+FIXME: Need to reimplement testandset
+
+#include "../test_and_set_t_is_char.h"
+
+#else
+
+#include "../test_and_set_t_is_ao_t.h"
+
+#endif
+
+#include <windows.h>
+       /* Seems like over-kill, but that's what MSDN recommends.       */
+       /* And apparently winbase.h is not always self-contained.       */
+
+
+#include <intrin.h>
+
+#pragma intrinsic (_ReadWriteBarrier)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LONGLONG __cdecl _InterlockedIncrement64(LONGLONG volatile *Addend);
+LONGLONG __cdecl _InterlockedDecrement64(LONGLONG volatile *Addend);
+LONGLONG __cdecl _InterlockedExchangeAdd64(LONGLONG volatile* Target,
+                                          LONGLONG Addend);
+LONGLONG __cdecl _InterlockedExchange64(LONGLONG volatile* Target,
+                                       LONGLONG Value);
+LONGLONG __cdecl _InterlockedCompareExchange64(LONGLONG volatile* Dest,
+                                               LONGLONG Exchange,
+                                              LONGLONG Comp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma intrinsic (_InterlockedIncrement64)
+#pragma intrinsic (_InterlockedDecrement64)
+#pragma intrinsic (_InterlockedExchange64)
+#pragma intrinsic (_InterlockedExchangeAdd64)
+#pragma intrinsic (_InterlockedCompareExchange64)
+
+/* As far as we can tell, the lfence and sfence instructions are not   */
+/* currently needed or useful for cached memory accesses.              */
+
+/* Unfortunately mfence doesn't exist everywhere.              */
+/* IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128) is                */
+/* probably a conservative test for it?                                */
+
+#if defined(AO_USE_PENTIUM4_INSTRS)
+
+AO_INLINE void
+AO_nop_full()
+{
+  __asm { mfence }
+}
+
+#define AO_HAVE_nop_full
+
+#else
+
+/* We could use the cpuid instruction.  But that seems to be slower    */
+/* than the default implementation based on test_and_set_full.  Thus   */
+/* we omit that bit of misinformation here.                            */
+
+#endif
+
+AO_INLINE AO_t
+AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
+{
+  return _InterlockedExchangeAdd64((LONGLONG volatile *)p, (LONGLONG)incr);
+}
+
+#define AO_HAVE_fetch_and_add_full
+
+AO_INLINE AO_t
+AO_fetch_and_add1_full (volatile AO_t *p)
+{
+  return _InterlockedIncrement64((LONGLONG volatile *)p) - 1;
+}
+
+#define AO_HAVE_fetch_and_add1_full
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_full (volatile AO_t *p)
+{
+  return _InterlockedDecrement64((LONGLONG volatile *)p) + 1;
+}
+
+#define AO_HAVE_fetch_and_sub1_full
+
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+                        AO_t old, AO_t new_val) 
+{
+    return _InterlockedCompareExchange64((LONGLONG volatile *)addr,
+                                         (LONGLONG)new_val, (LONGLONG)old)
+          == (LONGLONG)old;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+#if 0
+FIXME: (__asm not supported)
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+    __asm
+    {
+       mov     eax,AO_TS_SET           ;
+       mov     ebx,addr                ;
+       xchg    byte ptr [ebx],al       ;
+    }
+}
+
+#define AO_HAVE_test_and_set_full
+#endif
+
index 54ed757d6c4e78d43dd9689027913f3a6ac1eb5b..3b285b885b22f1af0d01302d52b18d795e646ad5 100644 (file)
@@ -28,7 +28,7 @@
 AO_INLINE unsigned short
 AO_short_load(volatile unsigned short *addr)
 {
-  assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(unsigned short) - 1)) == 0);
   /* Cast away the volatile for architectures like IA64 where  */
   /* volatile adds barrier semantics.                          */
   return (*(unsigned short *)addr);
@@ -39,7 +39,7 @@ AO_short_load(volatile unsigned short *addr)
 AO_INLINE void
 AO_short_store(volatile unsigned short *addr, unsigned short new_val)
 {
-  assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+  assert(((size_t)addr & (sizeof(unsigned short) - 1)) == 0);
   (*(unsigned short *)addr) = new_val;
 }