Mercurial > pub > ImplabNet
changeset 92:4c0e5ef99986 v2
rewritten tracing
line wrap: on
line diff
--- a/Implab.Diagnostics.Interactive/InteractiveListener.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab.Diagnostics.Interactive/InteractiveListener.cs Wed Oct 22 18:37:56 2014 +0400 @@ -107,11 +107,11 @@ base.Dispose(disposing); } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var item = new TraceViewItem { Indent = text.indent, Message = text.content, - Thread = context.ThreadId, + Thread = args.ThreadId, Channel = channel, Timestamp = Environment.TickCount };
--- a/Implab/Diagnostics/ConsoleTraceListener.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/ConsoleTraceListener.cs Wed Oct 22 18:37:56 2014 +0400 @@ -18,16 +18,16 @@ } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var msg = new StringBuilder(); for (int i = 0; i < text.indent; i++) msg.Append(" "); - msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content); + msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content); lock (_consoleLock) { - Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1); - Console.WriteLine(msg.ToString()); + Console.ForegroundColor = (ConsoleColor)(args.ThreadId % 15 + 1); + Console.WriteLine(msg); } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Diagnostics/Extensions.cs Wed Oct 22 18:37:56 2014 +0400 @@ -0,0 +1,15 @@ +namespace Implab.Diagnostics { + public static class Extensions { + public static IPromise<T> EndLogicalOperation<T>(this IPromise<T> promise) { + Safe.ArgumentNotNull(promise, "promise"); + var op = TraceContext.Instance.DetachLogicalOperation(); + + return promise.Anyway(() => { + TraceContext.Instance.EnterLogicalOperation(op,true); + TraceLog.EndLogicalOperation(); + TraceContext.Instance.Leave(); + }); + } + } +} +
--- a/Implab/Diagnostics/IEventTextFormatter.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/IEventTextFormatter.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,10 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace Implab.Diagnostics { +namespace Implab.Diagnostics { public interface IEventTextFormatter<in TEvent> { - EventText Format(TraceContext context, TEvent data); + EventText Format(LogEventArgs args, TEvent data); } }
--- a/Implab/Diagnostics/LogChannel.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/LogChannel.cs Wed Oct 22 18:37:56 2014 +0400 @@ -27,8 +27,8 @@ /// <summary> /// Событие появление новой записи в журнале, на это событие подписываются слушатели. /// </summary> - public event EventHandler<ValueEventArgs<TEvent>> Events; - + public event EventHandler<LogEventArgs<TEvent>> Events; + /// <summary> /// Имя канала, полезно для отображения в журнале /// </summary> @@ -63,19 +63,18 @@ /// </remarks> public void LogEvent(TEvent data) { var t = Events; - if (t!= null) - t(TraceContext.Current,new ValueEventArgs<TEvent>(data)); - } - - /// <summary> - /// Отправляет запись журнала через канал подписчикам. - /// </summary> - /// <param name="data">Запись журнала.</param> - /// <param name="context">Контекст трассировки от которого рассылается сообщение/</param> - public void LogEvent(TraceContext context,TEvent data) { - var t = Events; - if (t != null) - t(context, new ValueEventArgs<TEvent>(data)); + if (t != null) { + var traceContext = TraceContext.Instance; + t( + this, + new LogEventArgs<TEvent>( + data, + traceContext.ThreadId, + traceContext.CurrentOperation, + traceContext.CurrentOperation.Duration + ) + ); + } } } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Diagnostics/LogEventArgs.cs Wed Oct 22 18:37:56 2014 +0400 @@ -0,0 +1,24 @@ +using System; + +namespace Implab.Diagnostics { + public class LogEventArgs : EventArgs { + public int ThreadId { + get; + private set; + } + public LogicalOperation Operation { + get; + private set; + } + public int OperationTimeOffset { + get; + private set; + } + public LogEventArgs(int threadId, LogicalOperation operation, int timeOffset) { + ThreadId = threadId; + Operation = operation; + OperationTimeOffset = timeOffset; + } + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Diagnostics/LogEventArgsT.cs Wed Oct 22 18:37:56 2014 +0400 @@ -0,0 +1,13 @@ +namespace Implab.Diagnostics { + public class LogEventArgs<TEvent> : LogEventArgs { + public TEvent Value { + get; + private set; + } + + public LogEventArgs(TEvent value, int threadId, LogicalOperation operation, int timeOffset) : base(threadId, operation, timeOffset) { + Value = value; + } + } +} +
--- a/Implab/Diagnostics/LogicalOperation.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/LogicalOperation.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Implab.Diagnostics { public class LogicalOperation { + public static readonly LogicalOperation EMPTY = new LogicalOperation("__EMPTY__", null); + readonly LogicalOperation m_parent; readonly string m_name; readonly int m_level;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Diagnostics/OperationContext.cs Wed Oct 22 18:37:56 2014 +0400 @@ -0,0 +1,49 @@ +namespace Implab.Diagnostics { + struct OperationContext { + readonly LogicalOperation m_initial; + public readonly static OperationContext EMPTY = new OperationContext(LogicalOperation.EMPTY, false); + LogicalOperation m_current; + readonly bool m_ownership; + + public OperationContext(LogicalOperation operation, bool ownership) { + Safe.ArgumentNotNull(operation, "operation"); + + m_initial = operation; + m_current = operation; + m_ownership = ownership; + } + + public LogicalOperation CurrentOperation { + get { return m_current; } + } + + public void BeginLogicalOperation(string name) { + m_current = new LogicalOperation(name, m_current); + } + + public LogicalOperation DetachLogicalOperation() { + var detached = m_current; + if (m_current != LogicalOperation.EMPTY) { + if (m_current != m_initial) + m_current = m_current.Parent; + else if (m_ownership) + m_current = LogicalOperation.EMPTY; + else + detached = LogicalOperation.EMPTY; + } + TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context"); + return detached; + } + + public void EndLogicalOperation() { + if (m_current != m_initial) { + m_current = m_current.Parent; + } else if (m_current != null && m_ownership) { + m_current = null; + } else { + TraceLog.TraceWarning("EndLogicalOperation can't be applied in the current context"); + } + } + } +} +
--- a/Implab/Diagnostics/TextFileListener.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/TextFileListener.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; namespace Implab.Diagnostics { @@ -16,16 +14,16 @@ Register(this); } - protected override void WriteEntry(TraceContext context, EventText text, string channel) { + protected override void WriteEntry(LogEventArgs args, EventText text, string channel) { var msg = new StringBuilder(); for (int i = 0; i < text.indent; i++) msg.Append(" "); - msg.AppendFormat("[{0}]:{1}: {2}", context.ThreadId, channel, text.content); + msg.AppendFormat("[{0}]:{1}: {2}", args.ThreadId, channel, text.content); lock (m_textWriter) { if (!IsDisposed) { // тут гарантировано еще не освобожден m_textWriter - m_textWriter.WriteLine(msg.ToString()); + m_textWriter.WriteLine(msg); m_textWriter.Flush(); } }
--- a/Implab/Diagnostics/TextListenerBase.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/TextListenerBase.cs Wed Oct 22 18:37:56 2014 +0400 @@ -13,7 +13,7 @@ protected TextListenerBase(bool global) { Register(this); if (!global) { - m_boundOperation = TraceContext.Current.CurrentOperation; + m_boundOperation = TraceContext.Instance.CurrentOperation; m_baseIndent = Math.Max(0, m_boundOperation.Level - 1); } } @@ -38,13 +38,12 @@ var formatter = GetService<IEventTextFormatter<TEvent>>(); var channelName = channel.Name; - EventHandler<ValueEventArgs<TEvent>> handler = (sender, args) => { - TraceContext context = (TraceContext)sender; - var text = formatter.Format(context, args.Value); + EventHandler<LogEventArgs<TEvent>> handler = (sender, args) => { + var text = formatter.Format(args, args.Value); text.indent -= m_baseIndent; - if (IsRelated(context.CurrentOperation)) - WriteEntry(context, text, channelName); + if (IsRelated(args.Operation)) + WriteEntry(args, text, channelName); }; if (m_subscriptions.ContainsKey(channel)) @@ -97,19 +96,19 @@ /// Данный метод может вызваться из разных потоков одновременно. Возможна ситуация, когда /// данный метод вызывается уже после освобождения ообъекта методом <see cref="Dispose()"/>. /// </remarks> - /// <param name="context">Контекст трассировки.</param> /// <param name="text">Текст сообщения.</param> - protected abstract void WriteEntry(TraceContext context, EventText text, string channel); + /// <param name = "channel"></param> + protected abstract void WriteEntry(LogEventArgs args, EventText text, string channel); - public EventText Format(TraceContext context, object data) { + public EventText Format(LogEventArgs args, object data) { return new EventText { - indent = context.CurrentOperation.Level, + indent = args.Operation.Level, content = data.ToString() }; } - public EventText Format(TraceContext context, TraceEvent data) { - var level = context.CurrentOperation.Level; + public EventText Format(LogEventArgs args, TraceEvent data) { + var level = args.Operation.Level; if (data.EventType == TraceEventType.OperationCompleted || data.EventType == TraceEventType.OperationStarted) level--;
--- a/Implab/Diagnostics/TraceContext.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/TraceContext.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,238 +1,79 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -namespace Implab.Diagnostics { - /// <summary> - /// Контекст трассировки, привязывается к потоку и содержит в себе информацию о стеке логических операций. - /// </summary> - /// <remarks> - /// Контекст трассировки передается слушателям событий для определения места, где возникло событие. - /// </remarks> - public class TraceContext { - LogicalOperation m_currentOperation; - readonly LogicalOperation m_bound; - readonly int m_threadId; - - [ThreadStatic] - static TraceContext _current; - - /// <summary> - /// Текущий контекст трассировки для потока, создается астоматически при первом обращении. - /// </summary> - public static TraceContext Current { - get { - if (_current == null) { - _current = new TraceContext(); - _current.LogEvent(TraceEventType.Created,"[{0}]", _current.ThreadId); - } - return _current; - } - } - - TraceContext(TraceContext context) - : this(context, false) { - } - - TraceContext(TraceContext context, bool attach) { - if (context == null) - throw new ArgumentNullException("context"); - - m_currentOperation = context.CurrentOperation; - m_bound = attach ? context.BoundOperation : context.CurrentOperation; - m_threadId = Thread.CurrentThread.ManagedThreadId; - } - - TraceContext() { - m_currentOperation = new LogicalOperation(); - m_bound = m_currentOperation; - m_threadId = Thread.CurrentThread.ManagedThreadId; - } - - /// <summary> - /// При необходимости копирует состояние контекста трассивровки в текущий поток. - /// </summary> - /// <param name="from">Исходный контекст трассировки, который передается.</param> - /// <remarks> - /// <para> - /// Копирование происходит за счет создания нового контекста трассировки и заполнением его - /// состояния из переданного контекста. При этом копируется стек операций, однако в новом - /// контексте ранее начатые логические операции не могут быть завершены. - /// </para> - /// <para> - /// Если передача состояния состоялась, то вызывается событие трассировки <see cref="TraceEventType.Fork"/>. - /// </para> - /// </remarks> - public static void Fork(TraceContext from) { - if (_current == from) - return; - if (from != null) { - var context = new TraceContext(from); - context.LogEvent(TraceEventType.Fork, "[{0}]-->[{1}]",from.ThreadId, context.ThreadId); - _current = context; - } else { - _current = new TraceContext(); - } - } - - /// <summary> - /// Задает текущему потоку указанный контекст, текущей поток может заканчивать ранее начатые - /// логические операции в указанном контексте. - /// </summary> - /// <param name="source"></param> - public static void Attach(TraceContext source) { - if (_current == source) - return; - if (source != null) { - var context = new TraceContext(source, true); - context.LogEvent(TraceEventType.Attach, "[{0}]-->[{1}]", source.ThreadId, context.ThreadId); - _current = context; - } else { - _current = new TraceContext(); - } - } - - /// <summary> - /// Отсоединяет текущий контекст трассировки от потока, для дальнейшей его передачи другому потоку - /// <see cref="Attach(TraceContext)"/>. - /// </summary> - /// <returns>Контекст трассировки потока</returns> - /// <remarks> - /// После отсоединения контекста трассировки от потока, при первом обращении к трассировке в этом - /// потоке будет создан новый контекст. - /// </remarks> - public static TraceContext Detach() { - var context = Current; - context.LogEvent(TraceEventType.Detach, null); - _current = null; - return context; - } - - /// <summary> - /// Создает постоянную копию текущего контекста, данную копию можно хранить и использовать для передачи через <see cref="Fork(TraceContext)"/> - /// </summary> - /// <returns>Копия текущего контекста трассировки.</returns> - public static TraceContext Snapshot() { - return _current == null ? new TraceContext() : new TraceContext(_current,false); - } - - /// <summary> - /// Выполняет переданное действие в указанном контексте трассировки, по окончании восстанавливает предыдущий контекст трассировки потока. - /// </summary> - /// <param name="action"></param> - public void Invoke(Action action) { - if (action == null) - throw new ArgumentNullException("action"); - var old = _current; - Fork(this); - try { - action(); - } finally { - if(_current != null) - _current.EndAllOperations(); - _current = old; - } - } - - /// <summary> - /// Текущая логическая операция. - /// </summary> - public LogicalOperation CurrentOperation { - get { - return m_currentOperation; - } - } - - /// <summary> - /// Операция ниже которой нельзя опускаться в стеке логических операций, т.е. она не может быть завершена в текущем контексте. - /// </summary> - public LogicalOperation BoundOperation { - get { - return m_bound; - } - } - - /// <summary> - /// Поток, в котором создан контекст трассировки. - /// </summary> - public int ThreadId { - get { - return m_threadId; - } - } - - /// <summary> - /// Начинает безымянную логическую операцию. - /// </summary> - public void StartLogicalOperation() { - StartLogicalOperation(null); - } - - /// <summary> - /// Начинает логическую операцию с указанным именем. Созданная операция будет добвалена в стек логических операций контекста, затем будет создано соответсвующее событие. - /// </summary> - /// <param name="name">Имя начинаемой операции.</param> - public void StartLogicalOperation(string name) { - m_currentOperation = new LogicalOperation(name, m_currentOperation); - LogEvent(TraceEventType.OperationStarted, name); - } - - /// <summary> - /// Заканчивает логическую операцию начатую в текущем контексте. Операции, начатые в других контекстах не могут быть закончены в текущем контексте. - /// </summary> - /// <remarks> - /// При вызове данного метода создается событие журнала трассировки, либо о завершении операции, либо об ошибки, поскольку данная операция - /// начата в другом контексте. - /// </remarks> - public void EndLogicalOperation() { - if (m_bound == m_currentOperation) { - LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace"); - } else { - var op = m_currentOperation; - LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration); - m_currentOperation = m_currentOperation.Parent; - } - } - - /// <summary> - /// Создает копию контекста и возвращается на предыдущую операцию в текущем контексте, это позволяет начать операцию в одном потоке, а завершить - в другом. - /// </summary> - /// <returns>Контекст трассировки, который можно присоединить к другому потоку.</returns> - public TraceContext DetachLogicalOperation() { - if (m_bound == m_currentOperation) { - return new TraceContext(); - } else { - var detached = new TraceContext(this, true); - m_currentOperation = m_currentOperation.Parent; - return detached; - } - } - - public void BindLogicalOperationToPromise(IPromise promise) { - Safe.ArgumentNotNull(promise, "promise"); - - var ctx = DetachLogicalOperation(); - promise.Anyway(() => { - var old = _current; - TraceContext.Attach(ctx); - TraceContext.Current.EndLogicalOperation(); - _current = old; - }); - } - - /// <summary> - /// Заврешает все начатые в этом контексте операции - /// </summary> - public void EndAllOperations() { - while (m_bound != m_currentOperation) - EndLogicalOperation(); - } - - void LogEvent(TraceEventType type, string format, params object[] args) { - LogChannel<TraceEvent>.Default.LogEvent(this, TraceEvent.Create(type, format, args)); - } - } -} +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Implab.Diagnostics { + /// <summary> + /// Trace context is bound to the specific thread, each thread has it's own ThreadContext. + /// </summary> + /// <remarks> + /// ThreadContext manages relations between logical operations and threads. + /// </remarks> + public class TraceContext { + + [ThreadStatic] + static TraceContext _instance; + + OperationContext m_current = OperationContext.EMPTY; + readonly Stack<OperationContext> m_stack = new Stack<OperationContext>(); + readonly int m_threadId; + + public static TraceContext Instance { + get { + if (_instance == null) + _instance = new TraceContext(); + return _instance; + } + } + + public TraceContext() { + m_threadId = Thread.CurrentThread.ManagedThreadId; + } + + public int ThreadId { + get { return m_threadId; } + } + + public LogicalOperation CurrentOperation { + get { + return m_current.CurrentOperation; + } + } + + public void EnterLogicalOperation(LogicalOperation operation, bool takeOwnership) { + // TODO Emit event + m_stack.Push(m_current); + m_current = new OperationContext(operation, takeOwnership); + } + + public void StartLogicalOperation(string name) { + m_current.BeginLogicalOperation(name); + } + + public void StartLogicalOperation() { + // TODO Emit Event + m_current.BeginLogicalOperation(String.Empty); + } + + public void EndLogicalOperation() { + // TODO Emit event + m_current.EndLogicalOperation(); + } + + public LogicalOperation DetachLogicalOperation() { + // TODO Emit event + return m_current.DetachLogicalOperation(); + } + + public void Leave() { + // TODO Emit event + if (m_stack.Count > 0) + m_current = m_stack.Pop(); + else { + TraceLog.TraceWarning("Attemtp to leave the last operation context"); + m_current = OperationContext.EMPTY; + } + } + } +} +
--- a/Implab/Diagnostics/TraceLog.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Diagnostics/TraceLog.cs Wed Oct 22 18:37:56 2014 +0400 @@ -14,22 +14,17 @@ public static class TraceLog { [Conditional("TRACE")] public static void StartLogicalOperation() { - TraceContext.Current.StartLogicalOperation(); + TraceContext.Instance.StartLogicalOperation(); } [Conditional("TRACE")] public static void StartLogicalOperation(string name) { - TraceContext.Current.StartLogicalOperation(name); + TraceContext.Instance.StartLogicalOperation(name); } [Conditional("TRACE")] public static void EndLogicalOperation() { - TraceContext.Current.EndLogicalOperation(); - } - - [Conditional("TRACE")] - public static void BindLogicalOperationToPromise(IPromise promise) { - TraceContext.Current.BindLogicalOperationToPromise(promise); + TraceContext.Instance.EndLogicalOperation(); } [Conditional("TRACE")]
--- a/Implab/Implab.csproj Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Implab.csproj Wed Oct 22 18:37:56 2014 +0400 @@ -80,7 +80,6 @@ <Compile Include="Diagnostics\TextFileListener.cs" /> <Compile Include="Diagnostics\TextListenerBase.cs" /> <Compile Include="Diagnostics\TraceLog.cs" /> - <Compile Include="Diagnostics\TraceContext.cs" /> <Compile Include="Diagnostics\TraceEvent.cs" /> <Compile Include="Diagnostics\TraceEventType.cs" /> <Compile Include="Disposable.cs" /> @@ -141,6 +140,11 @@ <Compile Include="TransientPromiseException.cs" /> <Compile Include="SyncContextPromise.cs" /> <Compile Include="ObjectPool.cs" /> + <Compile Include="Diagnostics\OperationContext.cs" /> + <Compile Include="Diagnostics\TraceContext.cs" /> + <Compile Include="Diagnostics\LogEventArgs.cs" /> + <Compile Include="Diagnostics\LogEventArgsT.cs" /> + <Compile Include="Diagnostics\Extensions.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup />
--- a/Implab/Parallels/ArrayTraits.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Parallels/ArrayTraits.cs Wed Oct 22 18:37:56 2014 +0400 @@ -12,7 +12,7 @@ readonly Action<TSrc> m_action; readonly TSrc[] m_source; readonly Promise<int> m_promise = new Promise<int>(); - readonly TraceContext m_traceContext; + readonly LogicalOperation m_logicalOperation; int m_pending; int m_next; @@ -23,7 +23,7 @@ Debug.Assert(source != null); Debug.Assert(action != null); - m_traceContext = TraceContext.Snapshot(); + m_logicalOperation = TraceContext.Instance.CurrentOperation; m_next = 0; m_source = source; m_pending = source.Length; @@ -41,8 +41,12 @@ } protected override void Worker() { - TraceContext.Fork(m_traceContext); - base.Worker(); + TraceContext.Instance.EnterLogicalOperation(m_logicalOperation, false); + try { + base.Worker(); + } finally { + TraceContext.Instance.Leave(); + } } protected override bool TryDequeue(out int unit) { @@ -67,7 +71,7 @@ readonly TSrc[] m_source; readonly TDst[] m_dest; readonly Promise<TDst[]> m_promise = new Promise<TDst[]>(); - readonly TraceContext m_traceContext; + readonly LogicalOperation m_logicalOperation; int m_pending; int m_next; @@ -83,7 +87,7 @@ m_dest = new TDst[source.Length]; m_pending = source.Length; m_transform = transform; - m_traceContext = TraceContext.Snapshot(); + m_logicalOperation = TraceContext.Instance.CurrentOperation; m_promise.Anyway(Dispose); @@ -97,13 +101,17 @@ } protected override void Worker() { - TraceContext.Fork(m_traceContext); - base.Worker(); + TraceContext.Instance.EnterLogicalOperation(m_logicalOperation,false); + try { + base.Worker(); + } finally { + TraceContext.Instance.Leave(); + } } protected override bool TryDequeue(out int unit) { unit = Interlocked.Increment(ref m_next) - 1; - return unit >= m_source.Length ? false : true; + return unit < m_source.Length; } protected override void InvokeUnit(int unit) {
--- a/Implab/Parallels/AsyncPool.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Parallels/AsyncPool.cs Wed Oct 22 18:37:56 2014 +0400 @@ -14,15 +14,17 @@ public static IPromise<T> Invoke<T>(Func<T> func) { var p = new Promise<T>(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; ThreadPool.QueueUserWorkItem(param => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { p.Resolve(func()); } catch(Exception e) { p.Reject(e); - } + } finally { + TraceContext.Instance.Leave(); + } }); return p; @@ -31,14 +33,16 @@ public static IPromise<T> InvokeNewThread<T>(Func<T> func) { var p = new Promise<T>(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; var worker = new Thread(() => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { p.Resolve(func()); } catch (Exception e) { p.Reject(e); + } finally { + TraceContext.Instance.Leave(); } }); worker.IsBackground = true; @@ -51,15 +55,17 @@ public static IPromise InvokeNewThread(Action func) { var p = new Promise<object>(); - var caller = TraceContext.Snapshot(); + var caller = TraceContext.Instance.CurrentOperation; var worker = new Thread(() => { - TraceContext.Fork(caller); + TraceContext.Instance.EnterLogicalOperation(caller,false); try { func(); p.Resolve(); } catch (Exception e) { p.Reject(e); + } finally { + TraceContext.Instance.Leave(); } }); worker.IsBackground = true;
--- a/Implab/Parallels/DispatchPool.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Parallels/DispatchPool.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; -using System.Diagnostics; namespace Implab.Parallels { public abstract class DispatchPool<TUnit> : IDisposable { @@ -150,14 +146,13 @@ protected bool StartWorker() { if (AllocateThreadSlot()) { // slot successfully allocated - var worker = new Thread(this.Worker); + var worker = new Thread(Worker); worker.IsBackground = true; worker.Start(); return true; - } else { - return false; } + return false; } protected abstract void InvokeUnit(TUnit unit);
--- a/Implab/Parallels/WorkerPool.cs Tue Oct 14 09:30:45 2014 +0400 +++ b/Implab/Parallels/WorkerPool.cs Wed Oct 22 18:37:56 2014 +0400 @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using System.Diagnostics; using Implab.Diagnostics; @@ -12,29 +9,24 @@ MTQueue<Action> m_queue = new MTQueue<Action>(); int m_queueLength = 0; readonly int m_threshold = 1; - int m_workers = 0; public WorkerPool(int minThreads, int maxThreads, int threshold) : base(minThreads, maxThreads) { m_threshold = threshold; - m_workers = minThreads; InitPool(); } public WorkerPool(int minThreads, int maxThreads) : base(minThreads, maxThreads) { - m_workers = minThreads; InitPool(); } public WorkerPool(int threads) : base(threads) { - m_workers = threads; InitPool(); } - public WorkerPool() - : base() { + public WorkerPool() { InitPool(); } @@ -46,16 +38,17 @@ var promise = new Promise<T>(); - var caller = TraceContext.Snapshot(); + var lop = TraceContext.Instance.CurrentOperation; EnqueueTask(delegate() { - caller.Invoke(delegate() { - try { - promise.Resolve(task()); - } catch (Exception e) { - promise.Reject(e); - } - }); + TraceContext.Instance.EnterLogicalOperation(lop, false); + try { + promise.Resolve(task()); + } catch (Exception e) { + promise.Reject(e); + } finally { + TraceContext.Instance.Leave(); + } }); return promise;