开发者

.NET SpinLock not releasing Thread.BeginCriticalSection

开发者 https://www.devze.com 2023-02-22 15:50 出处:网络
Using .NET reflector, I find that the SpinLock structure has a lot of cases where it calls Thread.BeginCriticalRegion and doesn\'t call Thread.EndCriticalRegion.

Using .NET reflector, I find that the SpinLock structure has a lot of cases where it calls Thread.BeginCriticalRegion and doesn't call Thread.EndCriticalRegion. For example, in the public function SpinLock.Enter(ref bool lockTaken) (.NET 4.0):

// ...
Thread.BeginCriticalRegion();
if (Interlocked.CompareExchange(ref this.m_owner, managedThreadId, owner, ref lockTaken) == owner)
    return;  // <--- !!
Thread.EndCriticalRegion();
// ...

In another case, SpinLock.Exit seems to call Thread.EndCriticalRegion without having called Thread.BeginCriticalRegion.

public void Exit(bool useMemoryBarrier)
{
    if (this.IsThreadOwnerTrackingEnabled && !this.IsHeldByCurrentThread)
        throw ...

    if (useMemoryBarrier)
    {
        if (this.IsThreadOwnerTrackingEnabled)
            Interlocked.Exchange(ref this.m_owner, 0);
        else
            Interlocked.Decrement(ref this.m_owner);
    }
    else if (this.IsThreadOwnerTrackingEnabled)
        this.m_owner = 0;
    else
    {
        int owner = this.m_owner;
        this.m_owner = owner - 1;
    }
    Thread.EndCriticalRegion();   // <--- ??
}
开发者_运维百科

So the question: do any problems ensue from not balancing calls to Begin/EndCriticalRegion?


Note that the Begin/End calls do balance if the lock is actually taken and then released by calling Exit(). The calls to mark the critical region are necessary to let the CLR know that thread interruptions may be damaging while a SpinLock is acquired. See here for more info.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号