1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 8 using System.Collections.Generic; 9 using Antmicro.Renode.Core; 10 using Antmicro.Renode.Exceptions; 11 using Antmicro.Renode.Peripherals; 12 using Antmicro.Renode.Time; 13 14 namespace Antmicro.Renode.Network 15 { 16 public class BasicNetwork<TData, TAddress> : IExternal, IConnectable<IBasicNetworkNode<TData, TAddress>> 17 { BasicNetwork(string name)18 public BasicNetwork(string name) 19 { 20 this.sync = new object(); 21 this.name = name; 22 nodes = new List<IBasicNetworkNode<TData, TAddress>>(); 23 } 24 AttachTo(IBasicNetworkNode<TData, TAddress> node)25 public void AttachTo(IBasicNetworkNode<TData, TAddress> node) 26 { 27 lock(sync) 28 { 29 if(nodes.Contains(node)) 30 { 31 throw new RecoverableException($"Provided node is already registered in network '{name}'"); 32 } 33 34 node.TrySendData += SendData; 35 nodes.Add(node); 36 } 37 } 38 DetachFrom(IBasicNetworkNode<TData, TAddress> node)39 public void DetachFrom(IBasicNetworkNode<TData, TAddress> node) 40 { 41 lock(sync) 42 { 43 if(nodes.Remove(node)) 44 { 45 node.TrySendData -= SendData; 46 return; 47 } 48 49 throw new RecoverableException($"Provided node is not registered in network '{name}' and cannot be detached from it"); 50 } 51 } 52 SendData(TData data, TAddress source, TAddress destination)53 private bool SendData(TData data, TAddress source, TAddress destination) 54 { 55 var dataSent = false; 56 foreach(var node in GetMatchingNodes(destination)) 57 { 58 node.GetMachine().HandleTimeDomainEvent<object>((_) => node.ReceiveData(data, source, destination), null, TimeDomainsManager.Instance.VirtualTimeStamp); 59 dataSent = true; 60 } 61 return dataSent; 62 } 63 GetMatchingNodes(TAddress address)64 private IEnumerable<IBasicNetworkNode<TData, TAddress>> GetMatchingNodes(TAddress address) 65 { 66 lock(sync) 67 { 68 foreach(var node in nodes) 69 { 70 if(address.Equals(node.NodeAddress)) 71 { 72 yield return node; 73 } 74 } 75 } 76 } 77 78 private readonly List<IBasicNetworkNode<TData, TAddress>> nodes; 79 private readonly string name; 80 private readonly object sync; 81 } 82 } 83