Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,27 @@
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int CompareExchange32(ref int location1, int value, int comparand);

// This is used internally in cases where having a managed
// ref to the location is unsafe (Ex: it is the syncblock of a pinned object).
// The intrinsic expansion for this overload is exactly the same as for the `ref int`
// variant and will go on the same path since expansion is triggered by the name and
// return type of the method.
// The important part is avoiding `ref *location` in the unexpanded scenario, like
// in a case when compiling the Debug flavor of the app.
[Intrinsic]
internal static unsafe int CompareExchange(int* location1, int value, int comparand)
{
#if TARGET_X86 || TARGET_AMD64 || TARGET_ARM64 || TARGET_RISCV64
return CompareExchange(location1, value, comparand); // Must expand intrinsic
#else
Debug.Assert(location1 != null);

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-armel checked CoreCLR_NonPortable)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux_musl-arm Debug AllSubsets_CoreCLR_ReleaseRuntimeLibs)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-arm checked CoreCLR_ReleaseLibraries)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-arm Debug AllSubsets_CoreCLR_ReleaseRuntimeLibs)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux_musl-arm checked CoreCLR_ReleaseLibraries)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build browser-wasm linux Debug AllSubsets_CoreCLR)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-loongarch64 Debug CoreCLR_Bootstrapped)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context

Check failure on line 143 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L143

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(143,13): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'Debug' does not exist in the current context
return RuntimeImports.InterlockedCompareExchange(location1, value, comparand);

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-armel checked CoreCLR_NonPortable)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux_musl-arm Debug AllSubsets_CoreCLR_ReleaseRuntimeLibs)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-arm checked CoreCLR_ReleaseLibraries)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-arm Debug AllSubsets_CoreCLR_ReleaseRuntimeLibs)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux_musl-arm checked CoreCLR_ReleaseLibraries)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build browser-wasm linux Debug AllSubsets_CoreCLR)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime (Build linux-loongarch64 Debug CoreCLR_Bootstrapped)

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context

Check failure on line 144 in src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs

View check run for this annotation

Azure Pipelines / runtime

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs#L144

src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs(144,20): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'RuntimeImports' does not exist in the current context
#endif
}

[MethodImpl(MethodImplOptions.InternalCall)]
private static unsafe extern int CompareExchange32Pointer(int* location1, int value, int comparand);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

osx-arm64 build is failing, fix: #122753.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was it not detected by the CI?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like we don't have clr -c Debug, it's either with -rc checked, or not building clr subset. The closest to -rc Debug I've found is a leg in innerloop but that also only build clr.native subset:
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analyzers should run for all build flavors by default. I do not think we have any conditions that enable them for debug builds only.

Also, I am not able to reproduce the error on Windows (tried build -s clr.corelib -c debug locally). I am not able to reproduce the error locally even when with warnaserror+:IDE0036 passed directly on the csc command line when building CoreLib. I am not sure what's going on.


/// <summary>Compares two 64-bit signed integers for equality and, if they are equal, replaces the first value.</summary>
/// <param name="location1">The destination, whose value is compared with <paramref name="comparand"/> and possibly replaced.</param>
/// <param name="value">The value that replaces the destination value if the comparison results in equality.</param>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ private static unsafe HeaderLockResult TryAcquireThinLockSpin(object obj)
int newBits = oldBits + SBLK_LOCK_RECLEVEL_INC;
if ((newBits & SBLK_MASK_LOCK_RECLEVEL) != 0)
{
if (Interlocked.CompareExchange(ref *pHeader, newBits, oldBits) == oldBits)
if (Interlocked.CompareExchange(pHeader, newBits, oldBits) == oldBits)
{
return HeaderLockResult.Success;
}
Expand All @@ -170,7 +170,7 @@ private static unsafe HeaderLockResult TryAcquireThinLockSpin(object obj)
else if ((oldBits & SBLK_MASK_LOCK_THREADID) == 0)
{
int newBits = oldBits | currentThreadID;
if (Interlocked.CompareExchange(ref *pHeader, newBits, oldBits) == oldBits)
if (Interlocked.CompareExchange(pHeader, newBits, oldBits) == oldBits)
{
return HeaderLockResult.Success;
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/vm/ecalllist.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ FCFuncStart(gInterlockedFuncs)
FCFuncElement("Exchange64", COMInterlocked::Exchange64)
FCFuncElement("ExchangeObject", COMInterlocked::ExchangeObject)
FCFuncElement("CompareExchange32", COMInterlocked::CompareExchange32)
FCFuncElement("CompareExchange32Pointer", COMInterlocked::CompareExchange32)
FCFuncElement("CompareExchange64", COMInterlocked::CompareExchange64)
FCFuncElement("CompareExchangeObject", COMInterlocked::CompareExchangeObject)
FCFuncElement("ExchangeAdd32", COMInterlocked::ExchangeAdd32)
Expand Down
51 changes: 36 additions & 15 deletions src/coreclr/vm/syncblk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1735,7 +1735,30 @@ OBJECTHANDLE SyncBlock::GetOrCreateLock(OBJECTREF lockObj)

// We'll likely need to put this lock object into the sync block.
// Create the handle here.
OBJECTHANDLEHolder lockHandle = GetAppDomain()->CreateHandle(lockObj);
OBJECTHANDLE lockHandle = GetAppDomain()->CreateHandle(lockObj);

if (TryUpgradeThinLockToFullLock(lockHandle))
{
// Our lock instance is the one in the sync block now.
return lockHandle;
}

// Another thread beat us to the upgrade.
// Delete our GC handle.
DestroyHandle(lockHandle);

return VolatileLoad(&m_Lock);
}

bool SyncBlock::TryUpgradeThinLockToFullLock(OBJECTHANDLE lockHandle)
{
CONTRACTL
{
GC_TRIGGERS;
THROWS;
MODE_COOPERATIVE;
}
CONTRACTL_END;

// Switch to preemptive so we can grab the spin-lock.
// Use the NO_DTOR version so we don't do a coop->preemptive->coop transition on return.
Expand All @@ -1747,10 +1770,9 @@ OBJECTHANDLE SyncBlock::GetOrCreateLock(OBJECTREF lockObj)
GCX_PREEMP_NO_DTOR_END();

// Check again now that we hold the spin-lock
existingLock = m_Lock;
if (existingLock != (OBJECTHANDLE)NULL)
if (m_Lock != (OBJECTHANDLE)NULL)
{
return existingLock;
return false;
}

// We need to create a new lock
Expand All @@ -1761,32 +1783,31 @@ OBJECTHANDLE SyncBlock::GetOrCreateLock(OBJECTREF lockObj)

if (thinLock != 0)
{

// We have thin-lock info that needs to be transferred to the lock object.
DWORD lockThreadId = thinLock & SBLK_MASK_LOCK_THREADID;
DWORD recursionLevel = (thinLock & SBLK_MASK_LOCK_RECLEVEL) >> SBLK_RECLEVEL_SHIFT;
_ASSERTE(lockThreadId != 0);
PREPARE_NONVIRTUAL_CALLSITE(METHOD__LOCK__INITIALIZE_FOR_MONITOR);

// We have thin-lock info that needs to be transferred to the lock object.
OBJECTREF lockObj = ObjectFromHandle(lockHandle);

DECLARE_ARGHOLDER_ARRAY(args, 3);
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(ObjectFromHandle(lockHandle));
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(lockObj);
args[ARGNUM_1] = DWORD_TO_ARGHOLDER(lockThreadId);
args[ARGNUM_2] = DWORD_TO_ARGHOLDER(recursionLevel);
CALL_MANAGED_METHOD_NORET(args);
}

VolatileStore(&m_Lock, lockHandle.GetValue());

// Our lock instance is in the sync block now.
// Don't release it.
lockHandle.SuppressRelease();

// Also, clear the thin lock info.
VolatileStore(&m_Lock, lockHandle);
// Clear the thin lock info.
// It won't be used any more, but it will look out of date.
// Only clear the relevant bits, as the spin-lock bit is used to lock this method.
// That bit will be reset upon return.
m_thinLock.StoreWithoutBarrier(m_thinLock.LoadWithoutBarrier() & ~((SBLK_MASK_LOCK_THREADID) | (SBLK_MASK_LOCK_RECLEVEL)));

return lockHandle;
// Our lock instance is in the sync block now.
// Don't release it.
return true;
}
#endif // !DACCESS_COMPILE

Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/syncblk.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ class SyncBlock
private:
void InitializeThinLock(DWORD recursionLevel, DWORD threadId);

bool TryUpgradeThinLockToFullLock(OBJECTHANDLE lockHandle);

friend struct ::cdac_data<SyncBlock>;
};

Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/vm/syncblk.inl
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ FORCEINLINE ObjHeader::HeaderLockResult ObjHeader::AcquireHeaderThinLock(DWORD t
return HeaderLockResult::Success;
}

// Use the slow path instead of spinning. The compare-exchange above would not fail often, and it's not worth forcing the
// spin loop that typically follows the call to this function to check the recursive case, so just bail to the slow path.
return HeaderLockResult::UseSlowPath;
// We failed to acquire because someone touched other bits in the header.
return HeaderLockResult::Failure;
}

// Helper encapsulating the core logic for releasing monitor. Returns what kind of
Expand Down
Loading