]> granicus.if.org Git - libatomic_ops/commitdiff
2006-03-28 Hans Boehm <Hans.Boehm@hp.com>
authorhboehm <hboehm>
Tue, 28 Mar 2006 23:36:58 +0000 (23:36 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 25 Jul 2011 11:19:42 +0000 (15:19 +0400)
Integrate Earl Chew's atomic_ops improvements.  More details
are in the libatomic_ops ChangeLog.
* ChangeLog, src/atomic_ops.h, src/atomic_ops/sysdeps/gcc/powerpc.h,
src/atomic_ops/sysdeps/msftc/x86.h, tests/run_parallel.inc,
tests/test_atomic.c, tests/test_atomic_include.h.

ChangeLog
src/atomic_ops.h
src/atomic_ops/sysdeps/gcc/powerpc.h
src/atomic_ops/sysdeps/msftc/x86.h
tests/run_parallel.inc
tests/test_atomic.c
tests/test_atomic_include.h

index dcf2d43704224b8d475e981547cf02d2ca0247fd..77b9089df04a40438d969696fbe7e3dd9a39c8e8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2006-03-28 Earl Chew (Agilent)
+        * src/atomic_ops/sysdeps/gcc/powerpc.h: Remove unused variable cr.
+        * src/atomic_ops/sysdeps/msftc/x86.h:
+        Use new intrinsics available in MSVC 2003 and MSVC 2005.
+        Use inline assembler to generate mfence and byte sized xchg
+        Use correct prototype for InterlockedCompareExchange.
+        * src/atomic_ops.h: Add test for __PPC__ .
+        * tests/run_parallel.inc: Add simple VxWorks support.
+        * tests/test_atomic.c, tests/test_atomic_include.h: Add prototypes         to silence compiler warnings.
+
+2006-1-13 Hans Boehm <Hans.Boehm@hp.com>
+        *src/atomic_ops/sysdeps/gcc/powerpc.h: Beginnings of 64 bit support.
+        *src/atomic_ops/sysdeps/gcc/x86.h: Use "=q" for AO_test_and_set_full.
+
+2005-11-4 Hans Boehm <Hans.Boehm@hp.com>
+        *src/atomic_ops/sysdeps/gcc/ia64.h: Include
+        all_acquire_release_volatile.h, instead of just the pointer-sized
+        version.
+        *src/atomic_ops/sysdeps/gcc/ia64.h: Include
+        all_acquire_release_volatile.h and all_atomic_load_store.h,
+        instead of just the pointer-sized versions.
+
 [1.1 release]
 
 2003-09-27 Hans Boehm <Hans.Boehm@hp.com>
index 3a650305758ad8b4f85c5a38691750570ed41fc7..1feb37980f6a0daffbff0d574faaa042cb2dbf4d 100755 (executable)
 # if defined(__m68k__)
 #   include "atomic_ops/sysdeps/gcc/m68k.h"
 # endif /* __m68k__ */
-# if defined(__powerpc__) || defined(__ppc__)
+# if defined(__powerpc__) || defined(__ppc__) || defined(__PPC__)
 #   include "atomic_ops/sysdeps/gcc/powerpc.h"
 # endif /* __powerpc__ */
 # if defined(__arm__) && !defined(AO_USE_PTHREAD_DEFS)
index 5f33e71eee9dfc718d7b68cf050b129073b2d653..cd5a534ee6a3ddb1cc997dff64307f5919f8649e 100644 (file)
@@ -66,7 +66,6 @@ AO_lwsync()
 AO_INLINE AO_t
 AO_load_acquire(volatile AO_t *addr)
 {
-  int cr;
   AO_t result;
 
   /* FIXME: We should get gcc to allocate one of the condition */
index eac112c00e4b9c79cd2a9b4f8f9ed2fa85057810..1192d90e18691a64aa0a75f656103e723201c00e 100644 (file)
@@ -23,7 +23,7 @@
 /* The following really assume we have a 486 or better. */
 /* If ASSUME_WINDOWS98 is defined, we assume Windows 98 or newer.      */
 
-#include "../aligned_atomic_load_store.h"
+#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  */
 
 #include "../ordered_except_wr.h"
 
-#include "../test_and_set_t_is_ao_t.h"
-       /* We should use byte-sized test-and-set locations, as with     */
-       /* gcc.  But I couldn't find the appropriate compiler           */
-       /* intrinsic.   - HB                                            */
+#include "../test_and_set_t_is_char.h"
 
-#include <windows.h>
+#include <winbase.h>
+
+#if _MSC_VER < 1310
+
+#define _InterlockedIncrement       InterlockedIncrement
+#define _InterlockedDecrement       InterlockedDecrement
+#define _InterlockedExchange        InterlockedExchange 
+#define _InterlockedCompareExchange InterlockedCompareExchange
+
+#else
+
+#if _MSC_VER >= 1400
+#include <intrin.h>
+
+#pragma intrinsic (_ReadWriteBarrier)
+
+#else
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LONG __cdecl _InterlockedIncrement(LONG volatile *Addend);
+LONG __cdecl _InterlockedDecrement(LONG volatile *Addend);
+LONG __cdecl _InterlockedExchangeAdd(LONG volatile* Target, LONG Addend);
+LONG __cdecl _InterlockedExchange(LONG volatile* Target, LONG Value);
+LONG __cdecl _InterlockedCompareExchange(LONG volatile* Dest,
+                                         LONG Exchange, LONG Comp);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MSC_VER >= 1400 */
+
+#pragma intrinsic (_InterlockedIncrement)
+#pragma intrinsic (_InterlockedDecrement)
+#pragma intrinsic (_InterlockedExchange)
+#pragma intrinsic (_InterlockedExchangeAdd)
+#pragma intrinsic (_InterlockedCompareExchange)
+
+#endif /* _MSC_VER < 1310 */
 
 /* As far as we can tell, the lfence and sfence instructions are not   */
 /* currently needed or useful for cached memory accesses.              */
 
+AO_INLINE void
+AO_nop_full()
+{
+  __asm { mfence }
+}
+
+#define AO_HAVE_nop_full
+
+AO_INLINE AO_t
+AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
+{
+  return _InterlockedExchangeAdd((LONG volatile*)p, (LONG)incr);
+}
+
+#define AO_HAVE_fetch_and_add_full
+
 AO_INLINE AO_t
 AO_fetch_and_add1_full (volatile AO_t *p)
 {
-  return InterlockedIncrement((LONG volatile *)p) - 1;
+  return _InterlockedIncrement((LONG volatile *)p) - 1;
 }
 
 #define AO_HAVE_fetch_and_add1_full
@@ -55,7 +107,7 @@ AO_fetch_and_add1_full (volatile AO_t *p)
 AO_INLINE AO_t
 AO_fetch_and_sub1_full (volatile AO_t *p)
 {
-  return InterlockedDecrement((LONG volatile *)p) + 1;
+  return _InterlockedDecrement((LONG volatile *)p) + 1;
 }
 
 #define AO_HAVE_fetch_and_sub1_full
@@ -63,8 +115,12 @@ AO_fetch_and_sub1_full (volatile AO_t *p)
 AO_INLINE AO_TS_VAL_t
 AO_test_and_set_full(volatile AO_TS_t *addr)
 {
-  return (AO_TS_VAL_t) InterlockedExchange((LONG volatile *)addr,
-                                          (LONG)AO_TS_SET);
+    __asm
+    {
+       mov     eax,AO_TS_SET           ;
+       mov     ebx,addr                ;
+       xchg    byte ptr [ebx],al       ;
+    }
 }
 
 #define AO_HAVE_test_and_set_full
@@ -75,20 +131,14 @@ AO_INLINE int
 AO_compare_and_swap_full(volatile AO_t *addr,
                         AO_t old, AO_t new_val) 
 {
-# if 0
-    /* Use the pointer variant, since that should always have the right size. */
-    /* This seems to fail with VC++ 6 on Win2000 because the routine isn't    */
-    /* actually there.                                                       */
-    return InterlockedCompareExchangePointer((PVOID volatile *)addr,
-                                            (PVOID)new_val, (PVOID) old)
-          == (PVOID)old;
-# endif
-    /* FIXME - This is nearly useless on win64.                        */
-    /* Use InterlockedCompareExchange64 for win64?             */
-    return InterlockedCompareExchange((DWORD volatile *)addr,
-                                     (DWORD)new_val, (DWORD) old)
-          == (DWORD)old;
+    return _InterlockedCompareExchange((LONG volatile *)addr,
+                                       (LONG)new_val, (LONG)old)
+          == (LONG)old;
 }
 
 #define AO_HAVE_compare_and_swap_full
 #endif /* ASSUME_WINDOWS98 */
+
+#ifndef _WIN64
+#include "../ao_t_is_int.h"
+#endif
index 39308d5dda8b93d958ee43f647e433e10a81becc..1a87c8ba30f6d879d7cf7a90ffa1d248a9d617d3 100644 (file)
@@ -9,6 +9,8 @@
     defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) || \
     defined(_WIN32_WINCE)
 #  define USE_WINTHREADS
+#elif defined(__vxworks)
+#  define USE_VXTHREADS
 #else
 #  define USE_PTHREADS
 #endif
 # include <pthread.h>
 #endif
 
+#ifdef USE_VXTHREADS
+# include <vxworks.h>
+# include <taskLib.h>
+#endif
+
 #ifdef USE_WINTHREADS
 # include <windows.h>
 #endif
@@ -30,8 +37,10 @@ typedef void * (* thr_func)(void *);
 
 typedef int (* test_func)(void);       /* Returns != 0 on success */
 
+void * run_parallel(int nthreads, thr_func f1, test_func t, const char *name);
+
 #ifdef USE_PTHREADS
-void * run_parallel(int nthreads, thr_func f1, test_func t, char *name)
+void * run_parallel(int nthreads, thr_func f1, test_func t, const char *name)
 {
   pthread_attr_t attr;
   pthread_t thr[100];
@@ -87,6 +96,48 @@ void * run_parallel(int nthreads, thr_func f1, test_func t, char *name)
 }
 #endif /* USE_PTHREADS */
 
+#ifdef USE_VXTHREADS
+void * run_parallel(int nthreads, thr_func f1, test_func t, const char *name)
+{
+  int thr[100];
+  int i;
+
+  fprintf(stderr, "Testing %s\n", name);
+  if (nthreads > 100) 
+    {
+      fprintf(stderr, "run_parallel: requested too many threads\n");
+      taskSuspend(0);
+    }
+
+  for (i = 0; i < nthreads; ++i)
+    {
+      thr[i] = taskSpawn((char*) name, 180, 0, 32768, (FUNCPTR) f1, i,
+                         1, 2, 3, 4, 5, 6, 7, 8, 9);
+      if (thr[i] == ERROR)
+       {
+         fprintf(stderr, "taskSpawn failed with %d, thread %d\n",
+                         errno, i);
+         taskSuspend(0);
+        }
+    }
+  for (i = 0; i < nthreads; ++i)
+    {
+      while (taskIdVerify(thr[i]) == OK)
+        taskDelay(60);
+    }
+  if (t())
+    {
+      fprintf(stderr, "Succeeded\n");
+    }
+  else
+    {
+      fprintf(stderr, "Failed\n");
+      taskSuspend(0);
+    }
+  return 0;
+}
+#endif /* USE_VXTHREADS */
+
 #ifdef USE_WINTHREADS
 
 struct tramp_args {
@@ -101,7 +152,7 @@ DWORD WINAPI tramp(LPVOID param)
   return (DWORD)(args -> fn)((LPVOID)(args -> arg));
 }
 
-void * run_parallel(int nthreads, thr_func f1, test_func t, char *name)
+void * run_parallel(int nthreads, thr_func f1, test_func t, const char *name)
 {
   HANDLE thr[100];
   struct tramp_args args[100];
index 03da5f22b9b0aeb842a317f549898d11f16f5518..d31297da34d3440e664a09a9fd805615e40baab4 100644 (file)
 # define NITERS 10000000
 #endif
 
+void * add1sub1_thr(void * id);
+int add1sub1_test(void);
+void * acqrel_thr(void *id);
+int acqrel_test(void);
+void * test_and_set_thr(void * id);
+int test_and_set_test(void);
+
 #if defined(AO_HAVE_fetch_and_add1) && defined(AO_HAVE_fetch_and_sub1)
 
 AO_t counter = 0;
index c9970ab3626951dd65a3a41b15c3438aec4c4b8f..bc280ebd2a176d59712eeb5d804e67985f8010a2 100644 (file)
@@ -5,6 +5,15 @@
  * see doc/COPYING for details.
  */
 
+void test_atomic(void);
+void test_atomic_release(void);
+void test_atomic_acquire(void);
+void test_atomic_read(void);
+void test_atomic_write(void);
+void test_atomic_full(void);
+void test_atomic_release_write(void);
+void test_atomic_acquire_read(void);
+
 /* Some basic sanity tests.  These do not test the barrier semantics. */
 
 #undef TA_assert