aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionRegistry.cs23
-rw-r--r--src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs13
-rw-r--r--src/csharp/Grpc.Microbenchmarks/Program.cs5
3 files changed, 31 insertions, 10 deletions
diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
index f4aea685c3..b68655b33c 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs
@@ -19,7 +19,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
+using System.Threading;
using Grpc.Core.Logging;
using Grpc.Core.Utils;
@@ -35,7 +37,7 @@ namespace Grpc.Core.Internal
readonly GrpcEnvironment environment;
readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer());
- readonly object myLock = new object();
+ SpinLock spinLock = new SpinLock(Debugger.IsAttached);
IntPtr lastRegisteredKey; // only for testing
public CompletionRegistry(GrpcEnvironment environment)
@@ -46,11 +48,19 @@ namespace Grpc.Core.Internal
public void Register(IntPtr key, IOpCompletionCallback callback)
{
environment.DebugStats.PendingBatchCompletions.Increment();
- lock (myLock)
+
+ bool lockTaken = false;
+ try
{
+ spinLock.Enter(ref lockTaken);
+
dict.Add(key, callback);
this.lastRegisteredKey = key;
}
+ finally
+ {
+ if (lockTaken) spinLock.Exit();
+ }
}
public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback, object state)
@@ -68,11 +78,18 @@ namespace Grpc.Core.Internal
public IOpCompletionCallback Extract(IntPtr key)
{
IOpCompletionCallback value = null;
- lock (myLock)
+ bool lockTaken = false;
+ try
{
+ spinLock.Enter(ref lockTaken);
+
value = dict[key];
dict.Remove(key);
}
+ finally
+ {
+ if (lockTaken) spinLock.Exit();
+ }
environment.DebugStats.PendingBatchCompletions.Decrement();
return value;
}
diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
index 0e2fb070f1..2d1c33e9a0 100644
--- a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
+++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs
@@ -40,24 +40,25 @@ namespace Grpc.Microbenchmarks
GrpcEnvironment.ReleaseAsync().Wait();
}
- public void Run(int threadCount, int iterations)
+ public void Run(int threadCount, int iterations, bool useSharedRegistry)
{
- Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}", threadCount, iterations));
- var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations));
+ Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry));
+ CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment) : null;
+ var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry));
threadedBenchmark.Run();
// TODO: parametrize by number of pending completions
}
- private void ThreadBody(int iterations)
+ private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry)
{
- var completionRegistry = new CompletionRegistry(environment);
+ var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment);
var ctx = BatchContextSafeHandle.Create();
var stopwatch = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
completionRegistry.Register(ctx.Handle, ctx);
- var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey);
+ var callback = completionRegistry.Extract(ctx.Handle);
// NOTE: we are not calling the callback to avoid disposing ctx.
}
stopwatch.Stop();
diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs
index 79ec308501..a64c2979ab 100644
--- a/src/csharp/Grpc.Microbenchmarks/Program.cs
+++ b/src/csharp/Grpc.Microbenchmarks/Program.cs
@@ -77,7 +77,10 @@ namespace Grpc.Microbenchmarks
benchmark.Init();
foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12})
{
- benchmark.Run(threadCount, 4 * 1000 * 1000);
+ foreach (bool useSharedRegistry in new bool[] {false, true})
+ {
+ benchmark.Run(threadCount, 4 * 1000 * 1000, useSharedRegistry);
+ }
}
benchmark.Cleanup();
}