1 // 2 // Copyright (c) 2010-2018 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Threading; 9 using System.Collections.Generic; 10 using System.Collections.Concurrent; 11 using Antmicro.Renode.Utilities; 12 13 namespace Antmicro.Renode.Time 14 { 15 /// <summary> 16 /// Represents a helper class used to obtain a virtual time stamp of a current thread. 17 /// </summary> 18 public class TimeDomainsManager 19 { 20 public static TimeDomainsManager Instance = new TimeDomainsManager(); 21 22 /// <summary> 23 /// Registers a time stamp provider for the current thread. 24 /// </summary> RegisterCurrentThread(Func<TimeStamp> f)25 public IDisposable RegisterCurrentThread(Func<TimeStamp> f) 26 { 27 timeGetters.AddOrUpdate(Thread.CurrentThread.ManagedThreadId, f, (k, v) => f); 28 return new DisposableWrapper().RegisterDisposeAction(() => Instance.UnregisterCurrentThread()); 29 } 30 31 /// <summary> 32 /// Unregisters a time stamp provider for the current thread. 33 /// </summary> UnregisterCurrentThread()34 public void UnregisterCurrentThread() 35 { 36 var result = timeGetters.TryRemove(Thread.CurrentThread.ManagedThreadId, out var unused); 37 Renode.Debugging.DebugHelper.Assert(result, "Tried to unregister an unregistered thread."); 38 } 39 40 /// <summary> 41 /// Returns virtual time stamp for the current thread. 42 /// </summary> 43 public TimeStamp VirtualTimeStamp 44 { 45 get 46 { 47 if(!timeGetters.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var timestampGenerator)) 48 { 49 throw new ArgumentException($"Tried to obtain a virtual time stamp of an unregistered thread: '{Thread.CurrentThread.Name}'/{Thread.CurrentThread.ManagedThreadId}"); 50 } 51 return timestampGenerator(); 52 } 53 } 54 55 /// <summary> 56 /// Tries to obtain virtual time stamp for the current thread. 57 /// </summary> 58 /// <returns><c>true</c>, if virtual time stamp was obtained, <c>false</c> otherwise.</returns> 59 /// <param name="virtualTimeStamp">Virtual time stamp.</param> TryGetVirtualTimeStamp(out TimeStamp virtualTimeStamp)60 public bool TryGetVirtualTimeStamp(out TimeStamp virtualTimeStamp) 61 { 62 if(!timeGetters.TryGetValue(Thread.CurrentThread.ManagedThreadId, out var timestampGenerator)) 63 { 64 virtualTimeStamp = default(TimeStamp); 65 return false; 66 } 67 virtualTimeStamp = timestampGenerator(); 68 return true; 69 } 70 TimeDomainsManager()71 private TimeDomainsManager() 72 { 73 timeGetters = new ConcurrentDictionary<int, Func<TimeStamp>>(); 74 } 75 76 private readonly ConcurrentDictionary<int, Func<TimeStamp>> timeGetters; 77 } 78 } 79