Browse Source

Remove redundant lock.

Lock is evil.

This will actually affect the accuracy of GetDelta because
inboundDelta and outboundDelta may be calculated based on
the data collected at different time (eg. UpdateOutbound
get called before Interlocked.Read(ref _outbound)).

But that's not a problem. We can tolerate this little
inaccuracy. Besides, the _inbound, _outbound, _lastInbound
and _lastOutbound will be totally good because we use Interlocked.
tags/3.3
noisyfox Syrone Wong 9 years ago
parent
commit
0266ad9d59
1 changed files with 9 additions and 47 deletions
  1. +9
    -47
      shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs

+ 9
- 47
shadowsocks-csharp/Controller/Service/AvailabilityStatistics.cs View File

@@ -37,6 +37,7 @@ namespace Shadowsocks.Controller
private readonly ConcurrentDictionary<string, List<int>> _inboundSpeedRecords = new ConcurrentDictionary<string, List<int>>();
private readonly ConcurrentDictionary<string, List<int>> _outboundSpeedRecords = new ConcurrentDictionary<string, List<int>>();
private readonly ConcurrentDictionary<string, InOutBoundRecord> _inOutBoundRecords = new ConcurrentDictionary<string, InOutBoundRecord>();

private class InOutBoundRecord
{
private long _inbound;
@@ -44,65 +45,26 @@ namespace Shadowsocks.Controller
private long _outbound;
private long _lastOutbound;

private SpinLock _lock = new SpinLock();

public void UpdateInbound(long delta)
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
Interlocked.Add(ref _inbound, delta);
}
finally
{
if (lockTaken)
{
_lock.Exit(false);
}
}
Interlocked.Add(ref _inbound, delta);
}

public void UpdateOutbound(long delta)
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
Interlocked.Add(ref _outbound, delta);
}
finally
{
if (lockTaken)
{
_lock.Exit(false);
}
}
Interlocked.Add(ref _outbound, delta);
}

public void GetDelta(out long inboundDelta, out long outboundDelta)
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
var i = Interlocked.Read(ref _inbound);
var il = Interlocked.Exchange(ref _lastInbound, i);
inboundDelta = i - il;

var i = Interlocked.Read(ref _inbound);
var il = Interlocked.Exchange(ref _lastInbound, i);
inboundDelta = i - il;


var o = Interlocked.Read(ref _outbound);
var ol = Interlocked.Exchange(ref _lastOutbound, o);
outboundDelta = o - ol;
}
finally
{
if (lockTaken)
{
_lock.Exit(false);
}
}
var o = Interlocked.Read(ref _outbound);
var ol = Interlocked.Exchange(ref _lastOutbound, o);
outboundDelta = o - ol;
}
}



Loading…
Cancel
Save