Prechádzať zdrojové kódy

[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 rokov pred
rodič
commit
7ad425a495

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

@@ -12,6 +12,8 @@
 #ifndef __DXC_MICROCOM__
 #ifndef __DXC_MICROCOM__
 #define __DXC_MICROCOM__
 #define __DXC_MICROCOM__
 
 
+#include "llvm/Support/Atomic.h"
+
 template <typename TIface>
 template <typename TIface>
 class CComInterfaceArray {
 class CComInterfaceArray {
 private:
 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) \
 #define DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
     ULONG STDMETHODCALLTYPE AddRef() {\
     ULONG STDMETHODCALLTYPE AddRef() {\
-        return InterlockedIncrement(&m_dwRef); \
+        return (ULONG)llvm::sys::AtomicIncrement(&m_dwRef); \
     }
     }
 #define DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) \
 #define DXC_MICROCOM_ADDREF_RELEASE_IMPL(m_dwRef) \
     DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
     DXC_MICROCOM_ADDREF_IMPL(m_dwRef) \
     ULONG STDMETHODCALLTYPE Release() { \
     ULONG STDMETHODCALLTYPE Release() { \
-        ULONG result = InterlockedDecrement(&m_dwRef); \
+        ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef); \
         if (result == 0) delete this; \
         if (result == 0) delete this; \
         return result; \
         return result; \
     }
     }
@@ -101,23 +103,25 @@ void DxcCallDestructor(T *obj) {
 
 
 // The "TM" version keep an IMalloc field that, if not null, indicate
 // The "TM" version keep an IMalloc field that, if not null, indicate
 // ownership of 'this' and of any allocations used during release.
 // 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;
   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)
   DXC_MICROCOM_TM_ALLOC(T)
 #define DXC_MICROCOM_TM_CTOR_ONLY(T) \
 #define DXC_MICROCOM_TM_CTOR_ONLY(T) \
   T(IMalloc *pMalloc) : m_dwRef(0), m_pMalloc(pMalloc) { }
   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)
   DXC_MICROCOM_ADDREF_IMPL(m_dwRef)
   ULONG STDMETHODCALLTYPE Release() {
   ULONG STDMETHODCALLTYPE Release() {
     // Because blobs are also used by tests and utilities, we avoid using TLS.
     // 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) {
     if (result == 0) {
       CComPtr<IMalloc> pTmp(m_pMalloc);
       CComPtr<IMalloc> pTmp(m_pMalloc);
       this->~InternalDxcBlobEncoding();
       this->~InternalDxcBlobEncoding();
@@ -777,7 +777,7 @@ public:
   ULONG STDMETHODCALLTYPE Release() {
   ULONG STDMETHODCALLTYPE Release() {
     // Because memory streams are also used by tests and utilities,
     // Because memory streams are also used by tests and utilities,
     // we avoid using TLS.
     // we avoid using TLS.
-    ULONG result = InterlockedDecrement(&m_dwRef); \
+    ULONG result = (ULONG)llvm::sys::AtomicDecrement(&m_dwRef);
     if (result == 0) {
     if (result == 0) {
       CComPtr<IMalloc> pTmp(m_pMalloc);
       CComPtr<IMalloc> pTmp(m_pMalloc);
       this->~MemoryStream();
       this->~MemoryStream();

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

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

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

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

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

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

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

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