-
Notifications
You must be signed in to change notification settings - Fork 469
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Lukasz Rozmej <[email protected]> Co-authored-by: Szymon Kulec <[email protected]>
- Loading branch information
1 parent
65055f1
commit 159c2a4
Showing
4 changed files
with
123 additions
and
45 deletions.
There are no files selected for viewing
27 changes: 27 additions & 0 deletions
27
src/Nethermind/Nethermind.Core.Test/Threading/ConcurrencyControllerTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using FluentAssertions; | ||
using Nethermind.Core.Threading; | ||
using NUnit.Framework; | ||
|
||
namespace Nethermind.Core.Test.Threading; | ||
|
||
public class ConcurrencyControllerTests | ||
{ | ||
[Test] | ||
public void ThreadLimiterWillLimit() | ||
{ | ||
ConcurrencyController.Slot returner; | ||
ConcurrencyController limiter = new ConcurrencyController(3); | ||
|
||
limiter.TryTakeSlot(out returner).Should().Be(true); | ||
limiter.TryTakeSlot(out returner).Should().Be(true); | ||
limiter.TryTakeSlot(out returner).Should().Be(false); | ||
|
||
returner.Dispose(); | ||
|
||
limiter.TryTakeSlot(out returner).Should().Be(true); | ||
limiter.TryTakeSlot(out returner).Should().Be(false); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
src/Nethermind/Nethermind.Core/Threading/ConcurrencyController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// SPDX-FileCopyrightText: 2024 Demerzel Solutions Limited | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
|
||
using System; | ||
using System.Threading; | ||
|
||
namespace Nethermind.Core.Threading; | ||
|
||
/// <summary> | ||
/// Encapsulate the pattern of checking if new task can be spawned based on a predefined limit. | ||
/// Used in multithreaded tree visit where we don't know if we can spawn task or not and spawning task itself | ||
/// is not a cheap operation. | ||
/// | ||
/// Yes, I don't like the name. Give me a good one. | ||
/// </summary> | ||
/// <param name="concurrency">Desired concurrency which include the calling thread. So slot is slot-1.</param> | ||
public class ConcurrencyController(int concurrency) | ||
{ | ||
private int _slots = concurrency; | ||
|
||
public bool TryTakeSlot(out Slot returner) | ||
{ | ||
returner = new Slot(this); | ||
int newSlot = Volatile.Read(ref _slots); | ||
if (newSlot < 2) | ||
{ | ||
return false; | ||
} | ||
|
||
newSlot = Interlocked.Decrement(ref _slots); | ||
if (newSlot < 1) | ||
{ | ||
Interlocked.Increment(ref _slots); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
private void ReturnSlot() | ||
{ | ||
Interlocked.Increment(ref _slots); | ||
} | ||
|
||
public readonly struct Slot(ConcurrencyController limiter) : IDisposable | ||
{ | ||
public void Dispose() | ||
{ | ||
limiter.ReturnSlot(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters