瀏覽代碼

[linux-port] Use llvm::sys::Atomic* (#1309)

InterlockedIncrement and InterlockedDecrement are atomic operations to
increment or decrement the value pointed to by the pointer parameter and
return the same.

There are already platform abstractions available to LLVM in Atomics.h.
This change leverages them to implement the same functionality in a
platform-agnostic way. Mostly it's just a matter of swapping
InterlockedIncrement for AtomicIncrement.
Greg Roth 7 年之前
父節點
當前提交
7ad425a495

+ 23 - 19
include/dxc/Support/microcom.h

@@ -12,6 +12,8 @@
 #ifndef __DXC_MICROCOM__
 #define __DXC_MICROCOM__
 
+#include "llvm/Support/Atomic.h"
+
 template <typename TIface>
 class CComInterfaceArray {
 private:
@@ -73,15 +75,15 @@ public:
   }
 };
 
-#define DXC_MICROCOM_REF_FIELD(m_dwRef) volatile ULONG m_dwRef = 0;
+#define DXC_MICROCOM_REF_FIELD(m_dwRef) volatile llvm::sys::cas_flag m_dwRef = 0;
 #define DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
     ULONG STDMETHODCALLTYPE AddRef() {\
-        return InterlockedIncrement(&m_dwRef); \
+        return (ULONG)llvm::sys::AtomicIncrement(&m_dwRef); \
     }
 #define DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) \
     DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
     ULONG STDMETHODCALLTYPE Release() { \
-        ULONG result = InterlockedDecrement(&m_dwRef); \
+        ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef); \
         if (result == 0) delete this; \
         return result; \
     }
@@ -101,23 +103,25 @@ void DxcCallDestructor(T *obj) {
 
 // The "TM" version keep an IMalloc field that, if not null, indicate
 // ownership of 'this' and of any allocations used during release.
-#define DXC_MICROCOM_TM_REF_FIELDS() \
-  volatile ULONG m_dwRef = 0;\
+#define DXC_MICROCOM_TM_REF_FIELDS()                                           \
+  volatile llvm::sys::cas_flag m_dwRef = 0;                                    \
   CComPtr<IMalloc> m_pMalloc;
-#define DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL() \
-    DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
-    ULONG STDMETHODCALLTYPE Release() { \
-      ULONG result = InterlockedDecrement(&m_dwRef); \
-      if (result == 0) { \
-        CComPtr<IMalloc> pTmp(m_pMalloc); \
-        DxcThreadMalloc M(pTmp); \
-        DxcCallDestructor(this); \
-        pTmp->Free(this); \
-      } \
-      return result; \
-    }
-#define DXC_MICROCOM_TM_CTOR(T) \
-  DXC_MICROCOM_TM_CTOR_ONLY(T) \
+
+#define DXC_MICROCOM_TM_ADDREF_RELEASE_IMPL()                                  \
+  DXC_MICROCOM_ADDREF_IMPL(m_dwRef)                                            \
+  ULONG STDMETHODCALLTYPE Release() {                                          \
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef);                \
+    if (result == 0) {                                                         \
+      CComPtr<IMalloc> pTmp(m_pMalloc);                                        \
+      DxcThreadMalloc M(pTmp);                                                 \
+      DxcCallDestructor(this);                                                 \
+      pTmp->Free(this);                                                        \
+    }                                                                          \
+    return result;                                                             \
+  }
+
+#define DXC_MICROCOM_TM_CTOR(T)                                                \
+  DXC_MICROCOM_TM_CTOR_ONLY(T)                                                 \
   DXC_MICROCOM_TM_ALLOC(T)
 #define DXC_MICROCOM_TM_CTOR_ONLY(T) \
   T(IMalloc *pMalloc) : m_dwRef(0), m_pMalloc(pMalloc) { }

+ 2 - 2
lib/DxcSupport/FileIOHelper.cpp

@@ -185,7 +185,7 @@ public:
   DXC_MICROCOM_ADDREF_IMPL(m_dwRef)
   ULONG STDMETHODCALLTYPE Release() {
     // Because blobs are also used by tests and utilities, we avoid using TLS.
-    ULONG result = InterlockedDecrement(&m_dwRef);
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef);
     if (result == 0) {
       CComPtr<IMalloc> pTmp(m_pMalloc);
       this->~InternalDxcBlobEncoding();
@@ -777,7 +777,7 @@ public:
   ULONG STDMETHODCALLTYPE Release() {
     // Because memory streams are also used by tests and utilities,
     // we avoid using TLS.
-    ULONG result = InterlockedDecrement(&m_dwRef); \
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef);
     if (result == 0) {
       CComPtr<IMalloc> pTmp(m_pMalloc);
       this->~MemoryStream();

+ 1 - 0
tools/clang/tools/dxr/CMakeLists.txt

@@ -5,6 +5,7 @@
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
   dxcsupport
+  Support    # For Atomic increment/decrement
   )
 
 add_clang_executable(dxr

+ 4 - 3
tools/clang/unittests/HLSL/CompilationResult.h

@@ -23,6 +23,7 @@
 #include "dxc/dxcapi.h"
 #include "dxc/dxcisense.h"
 #include "dxc/Support/dxcapi.use.h"
+#include "llvm/Support/Atomic.h"
 
 inline HRESULT IFE(HRESULT hr) {
   if (FAILED(hr)) {
@@ -50,7 +51,7 @@ inline HRESULT GetFirstChildFromCursor(IDxcCursor *cursor,
 class TrivialDxcUnsavedFile : IDxcUnsavedFile
 {
 private:
-  volatile ULONG m_dwRef;
+  volatile llvm::sys::cas_flag m_dwRef;
   LPCSTR m_fileName;
   LPCSTR m_contents;
   unsigned m_length;
@@ -66,9 +67,9 @@ public:
     CComPtr<TrivialDxcUnsavedFile> pNewValue = new TrivialDxcUnsavedFile(fileName, contents);
     return pNewValue.QueryInterface(pResult);
   }
-  ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&m_dwRef); }
+  ULONG STDMETHODCALLTYPE AddRef() { return (ULONG)llvm::sys::AtomicIncrement(&m_dwRef); }
   ULONG STDMETHODCALLTYPE Release() { 
-    ULONG result = InterlockedDecrement(&m_dwRef);
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef);
     if (result == 0) delete this;
     return result;
   }

+ 4 - 3
tools/clang/unittests/HLSL/HlslTestUtils.h

@@ -13,6 +13,7 @@
 #include <fstream>
 #include "dxc/Support/Unicode.h"
 #include "dxc/HLSL/DxilConstants.h" // DenormMode
+#include "llvm/Support/Atomic.h"
 #include <dxgiformat.h>
 
 // If TAEF verify macros are available, use them to alias other legacy
@@ -479,11 +480,11 @@ inline UINT GetByteSizeForFormat(DXGI_FORMAT value) {
 
 
 #define SIMPLE_IUNKNOWN_IMPL1(_IFACE_) \
-  private: volatile ULONG m_dwRef; \
+  private: volatile llvm::sys::cas_flag m_dwRef; \
   public:\
-  ULONG STDMETHODCALLTYPE AddRef() { return InterlockedIncrement(&m_dwRef); } \
+  ULONG STDMETHODCALLTYPE AddRef() { return (ULONG)llvm::sys::AtomicIncrement(&m_dwRef); } \
   ULONG STDMETHODCALLTYPE Release() { \
-    ULONG result = InterlockedDecrement(&m_dwRef); \
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef); \
     if (result == 0) delete this; \
     return result; \
   } \

+ 1 - 0
tools/clang/unittests/HLSLHost/CMakeLists.txt

@@ -4,6 +4,7 @@
 
 set( LLVM_LINK_COMPONENTS
   ${LLVM_TARGETS_TO_BUILD}
+  Support    # For Atomic increment/decrement
   )
 
 add_clang_executable(HLSLHost