Hi mclow.lists, EricWF, majnemer,

MSVC does not implement the GCC atomic builtins. This patch emulates those 
needed by libc++ by forwarding to MS's interlocked intrinsic functions.

http://reviews.llvm.org/D5126

Files:
  include/__refstring
  include/support/win32/sync_win32.h
  src/exception.cpp
  src/locale.cpp
  src/memory.cpp
  src/new.cpp
Index: include/__refstring
===================================================================
--- include/__refstring
+++ include/__refstring
@@ -16,6 +16,8 @@
 #if __APPLE__
 #include <dlfcn.h>
 #include <mach-o/dyld.h>
+#elif defined(_LIBCPP_MSVC)
+#include <support/win32/sync_win32.h>
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
Index: include/support/win32/sync_win32.h
===================================================================
--- /dev/null
+++ include/support/win32/sync_win32.h
@@ -0,0 +1,93 @@
+// -*- C++ -*-
+//===--------------------- support/win32/sync_win32.h ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_SUPPORT_WIN32_SYNC_WIN32_H
+#define _LIBCPP_SUPPORT_WIN32_SYNC_WIN32_H
+
+#if !defined(_LIBCPP_MSVC)
+#error "This header complements Microsoft's Visual C++, and should not be included otherwise."
+#else
+
+#include <intrin.h>
+
+template <bool, class _Tp> struct __sync_win32_enable_if {};
+template <class _Tp> struct __sync_win32_enable_if<true, _Tp> {typedef _Tp type;};
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_add_and_fetch(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(long), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchangeAdd((long*)(__ptr), (long)(__val))) + __val;
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_add_and_fetch(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(__int64), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchangeAdd64((__int64*)(__ptr), (__int64)(__val))) + __val;
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_fetch_and_add(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(long), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchangeAdd((long*)(__ptr), (long)(__val)));
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_fetch_and_add(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(__int64), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchangeAdd64((__int64*)(__ptr), (__int64)(__val)));
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_lock_test_and_set(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(long), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchange((long*)(__ptr), (long)(__val)));
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY _Tp __sync_lock_test_and_set(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(__int64), _Tp>::type __val)
+{
+    return (_Tp)(_InterlockedExchange64((__int64*)(__ptr), (__int64)(__val)));
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY bool __sync_bool_compare_and_swap(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(long), _Tp>::type __old_val,
+    typename __sync_win32_enable_if<true, _Tp>::type __new_val)
+{
+    return _InterlockedCompareExchange((long*)(__ptr), (long)(__new_val),
+                                       (long)(__old_val)) == (long)(__old_val);
+}
+
+template <class _Tp>
+_LIBCPP_INLINE_VISIBILITY bool __sync_bool_compare_and_swap(
+    _Tp *__ptr,
+    typename __sync_win32_enable_if<sizeof(_Tp) == sizeof(__int64), _Tp>::type __old_val,
+    typename __sync_win32_enable_if<true, _Tp>::type __new_val)
+{
+    return _InterlockedCompareExchange64((__int64*)(__ptr), (__int64)(__new_val),
+                                         (__int64)(__old_val)) == (__int64)(__old_val);
+}
+
+#endif // _LIBCPP_MSVCRT
+
+#endif // _LIBCPP_SUPPORT_WIN32_SYNC_WIN32_H
Index: src/exception.cpp
===================================================================
--- src/exception.cpp
+++ src/exception.cpp
@@ -11,6 +11,9 @@
 
 #include "exception"
 #include "new"
+#if defined(_LIBCPP_MSVC)
+#include <support/win32/sync_win32.h>
+#endif
 
 #ifndef __has_include
 #define __has_include(inc) 0
Index: src/locale.cpp
===================================================================
--- src/locale.cpp
+++ src/locale.cpp
@@ -26,6 +26,9 @@
 #include "cstring"
 #include "cwctype"
 #include "__sso_allocator"
+#if defined(_LIBCPP_MSVC)
+#include <support/win32/sync_win32.h>
+#endif
 #if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
 #include <support/win32/locale_win32.h>
 #elif !defined(__ANDROID__)
Index: src/memory.cpp
===================================================================
--- src/memory.cpp
+++ src/memory.cpp
@@ -11,6 +11,9 @@
 #include "memory"
 #include "mutex"
 #include "thread"
+#if defined(_LIBCPP_MSVC)
+#include <support/win32/sync_win32.h>
+#endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD
 
Index: src/new.cpp
===================================================================
--- src/new.cpp
+++ src/new.cpp
@@ -12,6 +12,9 @@
 #include <stdlib.h>
 
 #include "new"
+#if defined(_LIBCPP_MSVC)
+#include <support/win32/sync_win32.h>
+#endif
 
 #ifndef __has_include
 #define __has_include(inc) 0
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to