From: ivmai Date: Thu, 10 Sep 2009 15:35:36 +0000 (+0000) Subject: 2009-09-10 Ivan Maidanski X-Git-Tag: libatomic_ops-7_2alpha4~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f2be2f0402a1eab9c0e59ede7d37818627dd91a2;p=libatomic_ops 2009-09-10 Ivan Maidanski (diff110) * src/atomic_ops/sysdeps/msftc/arm.h: New file (initial support for ARM family). * src/atomic_ops/sysdeps/msftc/common32_defs.h: New file. * src/atomic_ops/sysdeps/msftc/arm.h (AO_ASSUME_ARM_ARCH6): New macro. * src/atomic_ops/sysdeps/msftc/common32_defs.h (AO_USE_INTERLOCKED_INTRINSICS): Ditto. * src/atomic_ops/sysdeps/msftc/x86.h: Move "Interlocked" declarations to common32_defs.h. * src/atomic_ops/sysdeps/msftc/common32_defs.h (AO_INTERLOCKED_VOLATILE): New macro defined (used by Interlocked-based primitives) for compatibility with older VC++. * src/atomic_ops/sysdeps/msftc/common32_defs.h: Don't include missing if WinCE target. * src/atomic_ops/sysdeps/msftc/x86.h: Include common32_defs.h (define AO_USE_INTERLOCKED_INTRINSICS unconditionally). * src/atomic_ops/sysdeps/msftc/x86.h (AO_fetch_and_add_full, AO_fetch_and_add1_full, AO_fetch_and_sub1_full, AO_compare_and_swap_full): Move arch-independent primitives to common32_defs.h. * src/atomic_ops/sysdeps/msftc/x86.h: Remove comment about i486 or better CPU (since Interlocked Add and Xchg primitives are available on any 32-bit CPU). * src/atomic_ops.h: Include msftc/x86.h even if _M_IX86 is less than 400 (for i80386). * src/atomic_ops.h: Include msftc/x86.h if "x86" defined (for WinCE on x86). * src/atomic_ops.h: Include msftc/arm.h if ARM target (for WinCE). --- diff --git a/src/atomic_ops/sysdeps/msftc/arm.h b/src/atomic_ops/sysdeps/msftc/arm.h new file mode 100755 index 0000000..4ebc09b --- /dev/null +++ b/src/atomic_ops/sysdeps/msftc/arm.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#include "../read_ordered.h" + +#ifndef AO_ASSUME_WINDOWS98 + /* CAS is always available */ +# define AO_ASSUME_WINDOWS98 +#endif +#include "common32_defs.h" + +#ifdef AO_ASSUME_ARM_ARCH6 +/* ARMv6 is the first architecture providing support for simple LL/SC. */ + +#include "../standard_ao_double_t.h" + +/* If only a single processor is used, we can define AO_UNIPROCESSOR */ +/* and do not need to access CP15 for ensuring a DMB at all. */ +#ifdef AO_UNIPROCESSOR + AO_INLINE void AO_nop_full(void) {} +# define AO_HAVE_nop_full +#else +/* FIXME: implement AO_nop_full() */ +#endif + +AO_INLINE AO_t +AO_load(const volatile AO_t *addr) +{ + /* Cast away the volatile in case it adds fence semantics */ + return (*(const AO_t *)addr); +} + +#define AO_HAVE_load + +/* FIXME: implement AO_store() */ + +/* #include "../test_and_set_t_is_ao_t.h" */ +/* FIXME: implement AO_test_and_set() */ + +/* FIXME: implement AO_compare_double_and_swap_double() */ + +#endif /* AO_ASSUME_ARM_ARCH6 */ diff --git a/src/atomic_ops/sysdeps/msftc/common32_defs.h b/src/atomic_ops/sysdeps/msftc/common32_defs.h new file mode 100755 index 0000000..052647e --- /dev/null +++ b/src/atomic_ops/sysdeps/msftc/common32_defs.h @@ -0,0 +1,122 @@ +/* + * 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. + */ + +/* This file contains AO primitives based on VC++ built-in intrinsic */ +/* functions commonly available across 32-bit architectures. */ + +/* This file should be included from arch-specific header files. */ +/* Define AO_USE_INTERLOCKED_INTRINSICS if _Interlocked primitives */ +/* (used below) are available as intrinsic ones for a target arch */ +/* (otherwise "Interlocked" functions family is used instead). */ +/* Define AO_ASSUME_WINDOWS98 if CAS is available. */ + +#include + /* Seems like over-kill, but that's what MSDN recommends. */ + /* And apparently winbase.h is not always self-contained. */ + +#if _MSC_VER < 1310 || !defined(AO_USE_INTERLOCKED_INTRINSICS) + +# define _InterlockedIncrement InterlockedIncrement +# define _InterlockedDecrement InterlockedDecrement +# define _InterlockedExchange InterlockedExchange +# define _InterlockedExchangeAdd InterlockedExchangeAdd +# define _InterlockedCompareExchange InterlockedCompareExchange + +# define AO_INTERLOCKED_VOLATILE /**/ + +#else /* elif _MSC_VER >= 1310 */ + +# if _MSC_VER >= 1400 +# ifndef _WIN32_WCE +# include +# endif + +# pragma intrinsic (_ReadWriteBarrier) + +# else /* elif _MSC_VER < 1400 */ +# ifdef __cplusplus + extern "C" { +# endif + LONG __cdecl _InterlockedIncrement(LONG volatile *); + LONG __cdecl _InterlockedDecrement(LONG volatile *); + LONG __cdecl _InterlockedExchangeAdd(LONG volatile *, LONG); + LONG __cdecl _InterlockedExchange(LONG volatile *, LONG); + LONG __cdecl _InterlockedCompareExchange(LONG volatile *, + 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) + +# define AO_INTERLOCKED_VOLATILE volatile + +#endif /* _MSC_VER >= 1310 */ + +AO_INLINE AO_t +AO_fetch_and_add_full(volatile AO_t *p, AO_t incr) +{ + return _InterlockedExchangeAdd((LONG AO_INTERLOCKED_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 AO_INTERLOCKED_VOLATILE *)p) - 1; +} + +#define AO_HAVE_fetch_and_add1_full + +AO_INLINE AO_t +AO_fetch_and_sub1_full(volatile AO_t *p) +{ + return _InterlockedDecrement((LONG AO_INTERLOCKED_VOLATILE *)p) + 1; +} + +#define AO_HAVE_fetch_and_sub1_full + +#ifdef AO_ASSUME_WINDOWS98 +/* Returns nonzero if the comparison succeeded. */ +AO_INLINE int +AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) +{ +# ifdef AO_OLD_STYLE_INTERLOCKED_COMPARE_EXCHANGE + return _InterlockedCompareExchange((PVOID AO_INTERLOCKED_VOLATILE *)addr, + (PVOID)new_val, (PVOID)old) + == (PVOID)old; +# else + return _InterlockedCompareExchange((LONG AO_INTERLOCKED_VOLATILE *)addr, + (LONG)new_val, (LONG)old) + == (LONG)old; +# endif +} + +# define AO_HAVE_compare_and_swap_full +#endif /* AO_ASSUME_WINDOWS98 */