//
// 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;
}
}