Skip to content

Commit 98484de

Browse files
committed
Fix build
1 parent 1daa030 commit 98484de

File tree

5 files changed

+72
-50
lines changed

5 files changed

+72
-50
lines changed

src/libraries/Common/src/Interop/Unix/System.Native/Interop.IsQemuDetected.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Runtime.InteropServices;
5+
using System.Threading;
56

67
internal static partial class Interop
78
{
@@ -11,7 +12,22 @@ internal static partial class Sys
1112
[return: MarshalAs(UnmanagedType.Bool)]
1213
private static partial bool IsQemuDetectedImpl();
1314

14-
private static bool? _isQemuDetected;
15-
internal static bool IsQemuDetected() => _isQemuDetected ??= IsQemuDetectedImpl();
15+
private static int s_isQemuDetected;
16+
17+
internal static bool IsQemuDetected()
18+
{
19+
int isQemuDetected = Interlocked.CompareExchange(ref s_isQemuDetected, 0, 0);
20+
if (isQemuDetected == 0)
21+
{
22+
isQemuDetected = IsQemuDetectedImpl() ? 1 : 2;
23+
int oldValue = Interlocked.CompareExchange(ref s_isQemuDetected, isQemuDetected, 0);
24+
if (oldValue != 0) // a different thread has managed to update the value
25+
{
26+
isQemuDetected = oldValue;
27+
}
28+
}
29+
30+
return isQemuDetected == 1;
31+
}
1632
}
1733
}

src/libraries/Common/tests/TestUtilities/System/PlatformDetection.Unix.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static partial class PlatformDetection
3232
public static bool IsNotMonoLinuxArm64 => !IsMonoLinuxArm64;
3333

3434
public static bool IsQemuDetected =>
35-
#if TARGET_WINDOWS
35+
#if TARGET_WINDOWS || TARGET_BROWSER || TARGET_WASI
3636
false;
3737
#else
3838
Interop.Sys.IsQemuDetected();

src/native/libs/System.Native/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ set(NATIVE_SOURCES
3232
pal_time.c
3333
pal_datetime.c
3434
pal_sysctl.c
35-
"${CLR_SRC_NATIVE_DIR}/minipal/cpufeatures.c"
3635
)
3736

3837
list(APPEND NATIVE_SOURCES
@@ -48,6 +47,7 @@ if (NOT CLR_CMAKE_TARGET_WASI)
4847
pal_signal.c
4948
pal_threading.c
5049
pal_uid.c
50+
"${CLR_SRC_NATIVE_DIR}/minipal/cpufeatures.c"
5151
)
5252
else()
5353
list (APPEND NATIVE_SOURCES

src/native/libs/System.Native/pal_runtimeinformation.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,9 @@ int32_t SystemNative_GetOSArchitecture(void)
155155

156156
int32_t SystemNative_IsQemuDetected(void)
157157
{
158+
#ifdef TARGET_WASI
159+
return 0;
160+
#else
158161
return minipal_detect_qemu() ? 1 : 0;
162+
#endif
159163
}

src/native/minipal/cpufeatures.c

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
#include <sys/auxv.h>
2929
#include <asm/hwcap.h>
3030

31+
#ifdef __clang__
32+
#pragma clang diagnostic push
33+
#pragma clang diagnostic ignored "-Wunused-macros"
34+
#endif
35+
3136
// Light-up for hardware capabilities that are not present in older headers used by the portable build.
3237
#ifndef HWCAP_ASIMDRDM
3338
#define HWCAP_ASIMDRDM (1 << 12)
@@ -45,6 +50,14 @@
4550
#define HWCAP_SVE (1 << 22)
4651
#endif
4752

53+
#ifndef XSTATE_MASK_AVX512
54+
#define XSTATE_MASK_AVX512 (0xE0) /* 0b1110_0000 */
55+
#endif // XSTATE_MASK_AVX512
56+
57+
#ifdef __clang__
58+
#pragma clang diagnostic pop
59+
#endif
60+
4861
#endif
4962

5063
#if HAVE_SYSCTLBYNAME
@@ -56,7 +69,7 @@
5669
#if defined(HOST_UNIX)
5770
#if defined(HOST_X86) || defined(HOST_AMD64)
5871

59-
static uint32_t xmmYmmStateSupport()
72+
static uint32_t xmmYmmStateSupport(void)
6073
{
6174
uint32_t eax;
6275
__asm(" xgetbv\n" \
@@ -68,11 +81,7 @@ static uint32_t xmmYmmStateSupport()
6881
return ((eax & 0x06) == 0x06) ? 1 : 0;
6982
}
7083

71-
#ifndef XSTATE_MASK_AVX512
72-
#define XSTATE_MASK_AVX512 (0xE0) /* 0b1110_0000 */
73-
#endif // XSTATE_MASK_AVX512
74-
75-
static uint32_t avx512StateSupport()
84+
static uint32_t avx512StateSupport(void)
7685
{
7786
#if defined(HOST_APPLE)
7887
// MacOS has specialized behavior where it reports AVX512 support but doesnt
@@ -99,12 +108,12 @@ static uint32_t avx512StateSupport()
99108
#endif
100109
}
101110

102-
static bool IsAvxEnabled()
111+
static bool IsAvxEnabled(void)
103112
{
104113
return true;
105114
}
106115

107-
static bool IsAvx512Enabled()
116+
static bool IsAvx512Enabled(void)
108117
{
109118
return true;
110119
}
@@ -222,11 +231,11 @@ int minipal_getcpufeatures(void)
222231

223232
if (IsAvx512Enabled() && (avx512StateSupport() == 1)) // XGETBV XRC0[7:5] == 111
224233
{
225-
if (((cpuidInfo[CPUID_EBX] & (1 << 16)) != 0) && // AVX512F
226-
((cpuidInfo[CPUID_EBX] & (1 << 30)) != 0) && // AVX512BW
227-
((cpuidInfo[CPUID_EBX] & (1 << 28)) != 0) && // AVX512CD
228-
((cpuidInfo[CPUID_EBX] & (1 << 17)) != 0) && // AVX512DQ
229-
((cpuidInfo[CPUID_EBX] & (1 << 31)) != 0)) // AVX512VL
234+
if ((((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 16)) != 0) && // AVX512F
235+
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 30)) != 0) && // AVX512BW
236+
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 28)) != 0) && // AVX512CD
237+
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 17)) != 0) && // AVX512DQ
238+
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 31)) != 0)) // AVX512VL
230239
{
231240
// While the AVX-512 ISAs can be individually lit-up, they really
232241
// need F, BW, CD, DQ, and VL to be fully functional without adding
@@ -301,12 +310,12 @@ int minipal_getcpufeatures(void)
301310
}
302311
}
303312

304-
__cpuid(cpuidInfo, 0x80000000);
313+
__cpuid(cpuidInfo, (int)0x80000000);
305314
uint32_t maxCpuIdEx = (uint32_t)cpuidInfo[CPUID_EAX];
306315

307316
if (maxCpuIdEx >= 0x80000001)
308317
{
309-
__cpuid(cpuidInfo, 0x80000001);
318+
__cpuid(cpuidInfo, (int)0x80000001);
310319

311320
if ((cpuidInfo[CPUID_ECX] & (1 << 5)) != 0) // LZCNT
312321
{
@@ -441,67 +450,58 @@ int minipal_getcpufeatures(void)
441450
return result;
442451
}
443452

444-
// Detect if the current process is running under the Apple Rosetta x64 emulator
445-
bool minipal_detect_rosetta(void)
453+
static bool GetCpuBrand(char* brand, size_t bufferSize)
446454
{
447455
#if defined(HOST_AMD64) || defined(HOST_X86)
448456
// Check for CPU brand indicating emulation
449457
int regs[4];
450-
char brand[49];
451458

452459
// Get the maximum value for extended function CPUID info
453460
__cpuid(regs, (int)0x80000000);
454461
if ((unsigned int)regs[0] < 0x80000004)
455462
{
456-
return false; // Extended CPUID not supported
463+
brand[0] = '\0'; // Extended CPUID not supported, return empty string or handle error
464+
return false;
457465
}
458466

459-
// Retrieve the CPU brand string
467+
// Retrieve the CPU brand string directly into the caller-provided buffer
460468
for (unsigned int i = 0x80000002; i <= 0x80000004; ++i)
461469
{
462470
__cpuid(regs, (int)i);
463471
memcpy(brand + (i - 0x80000002) * sizeof(regs), regs, sizeof(regs));
464472
}
465-
brand[sizeof(brand) - 1] = '\0';
466473

467-
// Check if CPU brand indicates emulation
468-
if (strstr(brand, "VirtualApple") != NULL)
469-
{
470-
return true;
471-
}
472-
#endif // HOST_AMD64 || HOST_X86
474+
brand[bufferSize - 1] = '\0';
473475

476+
return true;
477+
#else
478+
(void)brand;
479+
(void)bufferSize;
474480
return false;
481+
#endif // HOST_AMD64 || HOST_X86
475482
}
476483

477-
bool minipal_detect_qemu(void)
484+
// Detect if the current process is running under the Apple Rosetta x64 emulator
485+
bool minipal_detect_rosetta(void)
478486
{
479-
#if defined(HOST_AMD64) || defined(HOST_X86)
480-
// Check for CPU brand indicating emulation
481-
unsigned int regs[4];
482487
char brand[49];
483488

484-
// Get the maximum value for extended function CPUID info
485-
__cpuid(0x80000000, regs[0], regs[1], regs[2], regs[3]);
486-
if (regs[0] < 0x80000004)
487-
{
488-
return false; // Extended CPUID not supported
489-
}
489+
// Check if CPU brand indicates emulation
490+
return GetCpuBrand(brand, sizeof(brand)) && (strstr(brand, "VirtualApple") != NULL);
491+
}
490492

491-
// Retrieve the CPU brand string
492-
for (unsigned int i = 0x80000002; i <= 0x80000004; ++i)
493-
{
494-
__cpuid(i, regs[0], regs[1], regs[2], regs[3]);
495-
memcpy(brand + (i - 0x80000002) * sizeof(regs), regs, sizeof(regs));
496-
}
497-
brand[sizeof(brand) - 1] = '\0';
493+
#if !defined(HOST_WINDOWS)
494+
495+
// Detect if the current process is running under QEMU
496+
bool minipal_detect_qemu(void)
497+
{
498+
char brand[49];
498499

499500
// Check if CPU brand indicates emulation
500-
if (strstr(brand, "QEMU") != NULL)
501+
if (GetCpuBrand(brand, sizeof(brand)) && strstr(brand, "QEMU") != NULL)
501502
{
502503
return true;
503504
}
504-
#endif
505505

506506
// Check for process name of PID 1 indicating emulation
507507
char cmdline[256];
@@ -535,3 +535,5 @@ bool minipal_detect_qemu(void)
535535

536536
return false;
537537
}
538+
539+
#endif // !HOST_WINDOWS

0 commit comments

Comments
 (0)