diff options
author | Jan Tattermusch <jtattermusch@google.com> | 2015-10-29 10:38:03 -0700 |
---|---|---|
committer | Jan Tattermusch <jtattermusch@google.com> | 2015-11-02 16:27:32 -0800 |
commit | 452ca9b912cf1173d901dc7ef0fcc4098d0ea551 (patch) | |
tree | 9bd4d87bc750eb21308e28750462771b7fb0a435 /src/csharp/Grpc.Core/Profiling | |
parent | 05e9e270a87ddf4fc115380c75a64eb2a1aa04d6 (diff) |
add profiling support
Diffstat (limited to 'src/csharp/Grpc.Core/Profiling')
-rw-r--r-- | src/csharp/Grpc.Core/Profiling/IProfiler.cs | 47 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs | 87 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Profiling/ProfilerScope.cs | 60 | ||||
-rw-r--r-- | src/csharp/Grpc.Core/Profiling/Profilers.cs | 131 |
4 files changed, 325 insertions, 0 deletions
diff --git a/src/csharp/Grpc.Core/Profiling/IProfiler.cs b/src/csharp/Grpc.Core/Profiling/IProfiler.cs new file mode 100644 index 0000000000..c426c365d2 --- /dev/null +++ b/src/csharp/Grpc.Core/Profiling/IProfiler.cs @@ -0,0 +1,47 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.IO; +using System.Threading; +using Grpc.Core.Internal; + +namespace Grpc.Core.Profiling +{ + internal interface IProfiler + { + void Begin(string tag); + void End(string tag); + void Mark(string tag); + } +} diff --git a/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs b/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs new file mode 100644 index 0000000000..5cc4c3c054 --- /dev/null +++ b/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs @@ -0,0 +1,87 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.IO; +using System.Threading; +using Grpc.Core.Internal; + +namespace Grpc.Core.Profiling +{ + internal struct ProfilerEntry + { + public enum Type { + BEGIN, + END, + MARK + } + + public ProfilerEntry(Timespec timespec, Type type, string tag) + { + this.timespec = timespec; + this.type = type; + this.tag = tag; + } + + public Timespec timespec; + public Type type; + public string tag; + + public override string ToString() + { + // mimic the output format used by C core. + return string.Format( + "{{\"t\": {0}.{1}, \"thd\":\"unknown\", \"type\": \"{2}\", \"tag\": \"{3}\", " + + "\"file\": \"unknown\", \"line\": 0, \"imp\": 0}}", + timespec.TimevalSeconds, timespec.TimevalNanos.ToString("D9"), + GetTypeAbbreviation(type), tag); + } + + internal static string GetTypeAbbreviation(Type type) + { + switch (type) + { + case Type.BEGIN: + return "{"; + + case Type.END: + return "}"; + + case Type.MARK: + return "."; + default: + throw new ArgumentException("Unknown type"); + } + } + } +} diff --git a/src/csharp/Grpc.Core/Profiling/ProfilerScope.cs b/src/csharp/Grpc.Core/Profiling/ProfilerScope.cs new file mode 100644 index 0000000000..413f3a1a35 --- /dev/null +++ b/src/csharp/Grpc.Core/Profiling/ProfilerScope.cs @@ -0,0 +1,60 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.IO; +using System.Threading; +using Grpc.Core.Internal; + +namespace Grpc.Core.Profiling +{ + // Allows declaring Begin and End of a profiler scope with a using statement. + // declared as struct for better performance. + internal struct ProfilerScope : IDisposable + { + readonly IProfiler profiler; + readonly string tag; + + public ProfilerScope(IProfiler profiler, string tag) + { + this.profiler = profiler; + this.tag = tag; + this.profiler.Begin(this.tag); + } + + public void Dispose() + { + profiler.End(tag); + } + } +} diff --git a/src/csharp/Grpc.Core/Profiling/Profilers.cs b/src/csharp/Grpc.Core/Profiling/Profilers.cs new file mode 100644 index 0000000000..c8123347f2 --- /dev/null +++ b/src/csharp/Grpc.Core/Profiling/Profilers.cs @@ -0,0 +1,131 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.IO; +using System.Threading; +using Grpc.Core.Internal; + +namespace Grpc.Core.Profiling +{ + internal static class Profilers + { + static readonly NopProfiler defaultProfiler = new NopProfiler(); + static readonly ThreadLocal<IProfiler> profilers = new ThreadLocal<IProfiler>(); + + public static IProfiler ForCurrentThread() + { + return profilers.Value ?? defaultProfiler; + } + + public static void SetForCurrentThread(IProfiler profiler) + { + profilers.Value = profiler; + } + + public static ProfilerScope NewScope(this IProfiler profiler, string tag) + { + return new ProfilerScope(profiler, tag); + } + } + + internal class NopProfiler : IProfiler + { + public void Begin(string tag) + { + } + + public void End(string tag) + { + } + + public void Mark(string tag) + { + } + } + + // Profiler using Timespec.PreciseNow + internal class BasicProfiler : IProfiler + { + ProfilerEntry[] entries; + int count; + + public BasicProfiler() : this(1024*1024) + { + } + + public BasicProfiler(int capacity) + { + this.entries = new ProfilerEntry[capacity]; + } + + public void Begin(string tag) { + AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.BEGIN, tag)); + } + + public void End(string tag) { + AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.END, tag)); + } + + public void Mark(string tag) { + AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.MARK, tag)); + } + + public void Reset() + { + count = 0; + } + + public void Dump(string filepath) + { + using (var stream = new StreamWriter(filepath)) + { + Dump(stream); + } + } + + public void Dump(TextWriter stream) + { + for (int i = 0; i < count; i++) + { + var entry = entries[i]; + stream.WriteLine(entry.ToString()); + } + } + + // NOT THREADSAFE! + void AddEntry(ProfilerEntry entry) { + entries[count++] = entry; + } + } +} |