Add T_CRITICAL_SECTION for cross OS DAC compile (#31908)
authorSteve MacLean <Steve.MacLean@microsoft.com>
Sat, 8 Feb 2020 01:36:33 +0000 (20:36 -0500)
committerGitHub <noreply@github.com>
Sat, 8 Feb 2020 01:36:33 +0000 (20:36 -0500)
* T_CRITICAL_SECTION for DAC

Add T_CRITICAL_SECTION as a cross OS version of CRITICAL_SECTION
Add platform defines for TARGET_<os> as needed.
Add verification code to keep T_CRITICAL_SECTION in sync with CRITICAL_SECTION

* Remove unused CRITICAL_SECTION & PAL_CRITICAL_SECTION fields

Remove LockSemaphore
Place unused field under `#if`

src/coreclr/configurecompiler.cmake
src/coreclr/src/inc/crosscomp.h
src/coreclr/src/pal/inc/pal.h
src/coreclr/src/pal/src/sync/cs.cpp
src/coreclr/src/vm/crst.cpp
src/coreclr/src/vm/crst.h

index 36cd285..db7b4d8 100644 (file)
@@ -354,6 +354,18 @@ if(CLR_CMAKE_TARGET_UNIX)
   add_definitions(-DTARGET_UNIX)
   # Contracts are disabled on UNIX.
   add_definitions(-DDISABLE_CONTRACTS)
+  if(CLR_CMAKE_TARGET_DARWIN)
+    add_definitions(-DTARGET_DARWIN)
+  endif(CLR_CMAKE_TARGET_DARWIN)
+  if(CLR_CMAKE_TARGET_FREEBSD)
+    add_definitions(-DTARGET_FREEBSD)
+  endif(CLR_CMAKE_TARGET_FREEBSD)
+  if(CLR_CMAKE_TARGET_LINUX)
+    add_definitions(-DTARGET_LINUX)
+  endif(CLR_CMAKE_TARGET_LINUX)
+  if(CLR_CMAKE_TARGET_NETBSD)
+    add_definitions(-DTARGET_NETBSD)
+  endif(CLR_CMAKE_TARGET_NETBSD)
 else(CLR_CMAKE_TARGET_UNIX)
   add_definitions(-DTARGET_WINDOWS)
 endif(CLR_CMAKE_TARGET_UNIX)
index 9d3a29e..0e20270 100644 (file)
@@ -393,6 +393,62 @@ typedef struct _T_KNONVOLATILE_CONTEXT_POINTERS {
 
 #endif
 
+#if defined(DAC_COMPILE) && defined(TARGET_UNIX)
+// This is a TARGET oriented copy of CRITICAL_SECTION and PAL_CS_NATIVE_DATA_SIZE
+// It is configured based on TARGET configuration rather than HOST configuration
+// There is validation code in src/coreclr/src/vm/crst.cpp to keep these from
+// getting out of sync
+
+#define T_CRITICAL_SECTION_VALIDATION_MESSAGE "T_CRITICAL_SECTION validation failed. It is not in sync with CRITICAL_SECTION"
+
+#if defined(TARGET_DARWIN) && defined(TARGET_X86)
+#define DAC_CS_NATIVE_DATA_SIZE 76
+#elif defined(TARGET_DARWIN) && defined(TARGET_AMD64)
+#define DAC_CS_NATIVE_DATA_SIZE 120
+#elif defined(TARGET_FREEBSD) && defined(TARGET_X86)
+#define DAC_CS_NATIVE_DATA_SIZE 12
+#elif defined(TARGET_FREEBSD) && defined(TARGET_AMD64)
+#define DAC_CS_NATIVE_DATA_SIZE 24
+#elif defined(TARGET_LINUX) && defined(TARGET_ARM)
+#define DAC_CS_NATIVE_DATA_SIZE 80
+#elif defined(TARGET_LINUX) && defined(TARGET_ARM64)
+#define DAC_CS_NATIVE_DATA_SIZE 116
+#elif defined(TARGET_LINUX) && defined(TARGET_X86)
+#define DAC_CS_NATIVE_DATA_SIZE 76
+#elif defined(TARGET_LINUX) && defined(TARGET_AMD64)
+#define DAC_CS_NATIVE_DATA_SIZE 96
+#elif defined(TARGET_NETBSD) && defined(TARGET_AMD64)
+#define DAC_CS_NATIVE_DATA_SIZE 96
+#elif defined(TARGET_NETBSD) && defined(TARGET_ARM)
+#define DAC_CS_NATIVE_DATA_SIZE 56
+#elif defined(TARGET_NETBSD) && defined(TARGET_X86)
+#define DAC_CS_NATIVE_DATA_SIZE 56
+#else
+#warning
+#error  DAC_CS_NATIVE_DATA_SIZE is not defined for this architecture
+#endif
+
+struct T_CRITICAL_SECTION {
+    PVOID DebugInfo;
+    LONG LockCount;
+    LONG RecursionCount;
+    HANDLE OwningThread;
+    ULONG_PTR SpinCount;
+
+#ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
+    BOOL bInternal;
+#endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
+    volatile DWORD dwInitState;
+
+    union CSNativeDataStorage
+    {
+        BYTE rgNativeDataStorage[DAC_CS_NATIVE_DATA_SIZE];
+        PVOID pvAlign; // make sure the storage is machine-pointer-size aligned
+    } csnds;
+};
+#else
+#define T_CRITICAL_SECTION CRITICAL_SECTION
+#endif
 
 #ifdef CROSSGEN_COMPILE
 void CrossGenNotSupported(const char * message);
index 7546046..9cfe2e8 100644 (file)
@@ -2377,11 +2377,13 @@ typedef struct _CRITICAL_SECTION {
     LONG LockCount;
     LONG RecursionCount;
     HANDLE OwningThread;
-    HANDLE LockSemaphore;
     ULONG_PTR SpinCount;
 
+#ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
     BOOL bInternal;
+#endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
     volatile DWORD dwInitState;
+
     union CSNativeDataStorage
     {
         BYTE rgNativeDataStorage[PAL_CS_NATIVE_DATA_SIZE];
index 138f971..3545500 100644 (file)
@@ -158,10 +158,11 @@ typedef struct _PAL_CRITICAL_SECTION {
     Volatile<LONG> LockCount;
     LONG RecursionCount;
     SIZE_T OwningThread;
-    HANDLE LockSemaphore;
     ULONG_PTR SpinCount;
     // Private Unix part
+#ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
     BOOL fInternal;
+#endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
     Volatile<PalCsInitState> cisInitState;
     PAL_CRITICAL_SECTION_NATIVE_DATA csndNativeData;
 } PAL_CRITICAL_SECTION, *PPAL_CRITICAL_SECTION, *LPPAL_CRITICAL_SECTION;
@@ -628,8 +629,6 @@ namespace CorUnix
         pPalCriticalSection->RecursionCount    = 0;
         pPalCriticalSection->SpinCount         = dwSpinCount;
         pPalCriticalSection->OwningThread      = 0;
-        pPalCriticalSection->LockSemaphore     = NULL;
-        pPalCriticalSection->fInternal         = fInternal;
 
 #ifdef _DEBUG
         CPalThread * pThread =
@@ -660,6 +659,7 @@ namespace CorUnix
         }
 
 #ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
+        pPalCriticalSection->fInternal         = fInternal;
         InterlockedIncrement(fInternal ?
             &g_lPALCSInternalInitializeCount : &g_lPALCSInitializeCount);
 #endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
@@ -1444,13 +1444,17 @@ namespace CorUnix
             printf("\tLockCount \t= %#x\n"
                    "\tRecursionCount \t= %d\n"
                    "\tOwningThread \t= %p\n"
-                   "\tLockSemaphore \t= %p\n"
                    "\tSpinCount \t= %u\n"
                    "\tfInternal \t= %d\n"
                    "\teInitState \t= %u\n"
                    "\tpNativeData \t= %p ->\n",
                    pCS->LockCount.Load(), pCS->RecursionCount, (void *)pCS->OwningThread,
-                   pCS->LockSemaphore, (unsigned)pCS->SpinCount, (int)pCS->fInternal,
+                   (unsigned)pCS->SpinCount,
+#ifdef PAL_TRACK_CRITICAL_SECTIONS_DATA
+                   (int)pCS->fInternal,
+#else
+                   (int)0,
+#endif // PAL_TRACK_CRITICAL_SECTIONS_DATA
                    pCS->cisInitState.Load(), &pCS->csndNativeData);
 
             printf("\t{\n\t\t[mutex]\n\t\t[condition]\n"
index 29a9b03..67985f8 100644 (file)
 #include <crsttypes.h>
 #undef __IN_CRST_CPP
 
+#if defined(DAC_COMPILE) && defined(TARGET_UNIX) && !defined(CROSS_COMPILE)
+    // Validate the DAC T_CRITICAL_SECTION matches the runtime CRITICAL section when we are not cross compiling.
+    // This is important when we are cross OS compiling the DAC
+    static_assert(PAL_CS_NATIVE_DATA_SIZE == DAC_CS_NATIVE_DATA_SIZE,     T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+    static_assert(sizeof(CRITICAL_SECTION) == sizeof(T_CRITICAL_SECTION), T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+
+    static_assert(offsetof(CRITICAL_SECTION, DebugInfo)      == offsetof(T_CRITICAL_SECTION, DebugInfo),      T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+    static_assert(offsetof(CRITICAL_SECTION, LockCount)      == offsetof(T_CRITICAL_SECTION, LockCount),      T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+    static_assert(offsetof(CRITICAL_SECTION, RecursionCount) == offsetof(T_CRITICAL_SECTION, RecursionCount), T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+    static_assert(offsetof(CRITICAL_SECTION, OwningThread)   == offsetof(T_CRITICAL_SECTION, OwningThread),   T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+    static_assert(offsetof(CRITICAL_SECTION, SpinCount)      == offsetof(T_CRITICAL_SECTION, SpinCount),      T_CRITICAL_SECTION_VALIDATION_MESSAGE);
+#endif // defined(DAC_COMPILE) && defined(TARGET_UNIX) && !defined(CROSS_COMPILE)
+
 #ifndef DACCESS_COMPILE
 Volatile<LONG> g_ShutdownCrstUsageCount = 0;
 
index 1457a7b..dd10beb 100644 (file)
@@ -296,9 +296,7 @@ protected:
     void DebugDestroy();
 #endif
 
-    union {
-        CRITICAL_SECTION    m_criticalsection;
-    };
+    T_CRITICAL_SECTION m_criticalsection;
 
     typedef enum
     {