// // Copyright (c) 2010-2018 Antmicro // // This file is licensed under the MIT License. // Full license text is available in 'licenses/MIT.txt'. // using System; using System.Threading; using System.Collections.Generic; using System.Collections.Concurrent; using Antmicro.Renode.Utilities; namespace Antmicro.Renode.Time { /// /// Represents a helper class used to obtain a virtual time stamp of a current thread. /// public class TimeDomainsManager { public static TimeDomainsManager Instance = new TimeDomainsManager(); /// /// Registers a time stamp provider for the current thread. /// public IDisposable RegisterCurrentThread(Func f) { timeGetters.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, f, (k, v) => f); return new DisposableWrapper().RegisterDisposeAction(() => Instance.UnregisterCurrentThread()); } /// /// Unregisters a time stamp provider for the current thread. /// public void UnregisterCurrentThread() { var result = timeGetters.TryRemove(Thread.CurrentThread.ManagedThreadId, out var unused); Renode.Debugging.DebugHelper.Assert(result, "Tried to unregister an unregistered thread."); } /// /// Returns virtual time stamp for the current thread. /// public TimeStamp VirtualTimeStamp { get { if(!timeGetters.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var timestampGenerator)) { throw new ArgumentException($"Tried to obtain a virtual time stamp of an unregistered thread: '{Thread.CurrentThread.Name}'/{Thread.CurrentThread.ManagedThreadId}"); } return timestampGenerator(); } } /// /// Tries to obtain virtual time stamp for the current thread. /// /// true, if virtual time stamp was obtained, false otherwise. /// Virtual time stamp. public bool TryGetVirtualTimeStamp(out TimeStamp virtualTimeStamp) { if(!timeGetters.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var timestampGenerator)) { virtualTimeStamp = default(TimeStamp); return false; } virtualTimeStamp = timestampGenerator(); return true; } private TimeDomainsManager() { timeGetters = new ConcurrentDictionary>(); } private readonly ConcurrentDictionary> timeGetters; } }