1 #region Copyright notice and license 2 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 #endregion 18 19 using System; 20 using System.IO; 21 using System.Threading; 22 using Grpc.Core.Internal; 23 24 namespace Grpc.Core.Profiling 25 { 26 internal static class Profilers 27 { 28 static readonly NopProfiler DefaultProfiler = new NopProfiler(); 29 static readonly ThreadLocal<IProfiler> profilers = new ThreadLocal<IProfiler>(); 30 ForCurrentThread()31 public static IProfiler ForCurrentThread() 32 { 33 return profilers.Value ?? DefaultProfiler; 34 } 35 SetForCurrentThread(IProfiler profiler)36 public static void SetForCurrentThread(IProfiler profiler) 37 { 38 profilers.Value = profiler; 39 } 40 NewScope(this IProfiler profiler, string tag)41 public static ProfilerScope NewScope(this IProfiler profiler, string tag) 42 { 43 return new ProfilerScope(profiler, tag); 44 } 45 } 46 47 internal class NopProfiler : IProfiler 48 { Begin(string tag)49 public void Begin(string tag) 50 { 51 } 52 End(string tag)53 public void End(string tag) 54 { 55 } 56 Mark(string tag)57 public void Mark(string tag) 58 { 59 } 60 } 61 62 // Profiler using Timespec.PreciseNow 63 internal class BasicProfiler : IProfiler 64 { 65 ProfilerEntry[] entries; 66 int count; 67 BasicProfiler()68 public BasicProfiler() : this(20*1024*1024) 69 { 70 } 71 BasicProfiler(int capacity)72 public BasicProfiler(int capacity) 73 { 74 this.entries = new ProfilerEntry[capacity]; 75 } 76 Begin(string tag)77 public void Begin(string tag) 78 { 79 AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.BEGIN, tag)); 80 } 81 End(string tag)82 public void End(string tag) 83 { 84 AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.END, tag)); 85 } 86 Mark(string tag)87 public void Mark(string tag) 88 { 89 AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.MARK, tag)); 90 } 91 Reset()92 public void Reset() 93 { 94 count = 0; 95 } 96 Dump(string filepath)97 public void Dump(string filepath) 98 { 99 using (var stream = File.CreateText(filepath)) 100 { 101 Dump(stream); 102 } 103 } 104 Dump(TextWriter stream)105 public void Dump(TextWriter stream) 106 { 107 for (int i = 0; i < count; i++) 108 { 109 var entry = entries[i]; 110 stream.WriteLine(entry.ToString()); 111 } 112 } 113 114 // NOT THREADSAFE! AddEntry(ProfilerEntry entry)115 void AddEntry(ProfilerEntry entry) { 116 entries[count++] = entry; 117 } 118 } 119 } 120