/// <summary> /// Initialize SharedConfigMemoryRegion. /// </summary> /// <param name="sharedConfigMemoryRegion"></param> /// <returns></returns> public static SharedConfigMemoryRegion InitializeMemoryRegion(this SharedConfigMemoryRegion sharedConfigMemoryRegion) { // Initialize memory allocator. // var allocator = sharedConfigMemoryRegion.Allocator; allocator.AllocationBlockOffset = Utils.Align((uint)sharedConfigMemoryRegion.CodegenTypeSize(), 256); allocator.AllocationBlockSize = (uint)sharedConfigMemoryRegion.MemoryHeader.MemoryRegionSize - allocator.AllocationBlockOffset; allocator.FreeOffset = allocator.AllocationBlockOffset; allocator.AllocationCount = 0; allocator.LastAllocatedOffset = 0; // Allocate array for shared config offsets. // uint elementCount = 2048; AllocationEntry allocationEntry = sharedConfigMemoryRegion.Allocate(default(UIntArray).CodegenTypeSize() + (sizeof(uint) * elementCount)); sharedConfigMemoryRegion.ConfigsArrayOffset = (uint)allocationEntry.Buffer.Offset(sharedConfigMemoryRegion.Buffer) + (uint)default(AllocationEntry).CodegenTypeSize(); UIntArray configsOffsetArray = sharedConfigMemoryRegion.ConfigsOffsetArray; configsOffsetArray.Count = elementCount; return(sharedConfigMemoryRegion); }
/// <summary> /// Internal lookup. TProxy type is deduced by the caller. /// </summary> /// <typeparam name="TProbingPolicy">HashTable lookup policy.</typeparam> /// <typeparam name="TProxy">Codegen proxy type.</typeparam> /// <param name="sharedConfigMemoryRegion"></param> /// <param name="codegenKey"></param> /// <param name="slotIndex"></param> /// <returns></returns> public static SharedConfig <TProxy> Get <TProbingPolicy, TProxy>( this SharedConfigMemoryRegion sharedConfigMemoryRegion, ICodegenKey codegenKey, ref uint slotIndex) where TProbingPolicy : IProbingPolicy where TProxy : ICodegenProxy, new() { TProbingPolicy probingPolicy = default; uint probingCount = 0; slotIndex = 0; var configsArray = new UIntArray() { Buffer = sharedConfigMemoryRegion.Buffer + (int)sharedConfigMemoryRegion.ConfigsArrayOffset }; uint elementCount = configsArray.Count; ProxyArray <uint> sharedConfigsOffsets = configsArray.Elements; SharedConfig <TProxy> sharedConfig = default; while (true) { slotIndex = probingPolicy.CalculateIndex(codegenKey, ref probingCount, elementCount); uint sharedConfigOffsets = sharedConfigsOffsets[(int)slotIndex]; if (sharedConfigOffsets == 0) { // Slot entry is empty. // sharedConfig.Buffer = IntPtr.Zero; break; } // Compare the object keys. // Create a proxy to the shared config. // sharedConfig.Buffer = sharedConfigMemoryRegion.Buffer + (int)sharedConfigOffsets; // Compare key with the proxy. // bool foundEntry = codegenKey.CodegenTypeIndex() == sharedConfig.Header.CodegenTypeIndex && codegenKey.CompareKey(sharedConfig.Config); if (foundEntry) { break; } ++probingCount; } return(sharedConfig); }
public static T Allocate <T>(this SharedConfigMemoryRegion sharedConfigMemoryRegion) where T : ICodegenProxy, new() { AllocationEntry allocationEntry = sharedConfigMemoryRegion.Allocate(default(T).CodegenTypeSize()); T codegenProxy = new T() { Buffer = allocationEntry.Buffer + (int)default(AllocationEntry).CodegenTypeSize() }; return(codegenProxy); }
/// <summary> /// Initialize SharedConfigMemoryRegion. /// </summary> /// <param name="sharedConfigMemoryRegion"></param> /// <returns></returns> public static SharedConfigMemoryRegion InitializeMemoryRegion(this SharedConfigMemoryRegion sharedConfigMemoryRegion) { var sharedConfigDictionary = sharedConfigMemoryRegion.SharedConfigDictionary; var allocator = sharedConfigDictionary.Allocator; // Initialize memory allocator. // allocator.InitializeArenaAllocator(sharedConfigMemoryRegion.MemoryHeader, (int)sharedConfigMemoryRegion.CodegenTypeSize()); // Initialize shared config dictionary. // sharedConfigDictionary.InitializeSharedConfigDictionary(); return(sharedConfigMemoryRegion); }
internal void Initalize(SharedMemoryRegionView <T> sharedMemory) { if (typeof(T) == typeof(GlobalMemoryRegion)) { GlobalMemoryRegion globalMemoryRegion = (GlobalMemoryRegion)(object)sharedMemory.MemoryRegion(); globalMemoryRegion.InitializeMemoryRegion(); } else if (typeof(T) == typeof(SharedConfigMemoryRegion)) { SharedConfigMemoryRegion sharedMemoryRegionView = (SharedConfigMemoryRegion)(object)sharedMemory.MemoryRegion(); sharedMemoryRegionView.InitializeMemoryRegion(); } else { throw new ArgumentException("Unsupported memory region type."); } }
public static AllocationEntry Allocate(this SharedConfigMemoryRegion sharedConfigMemoryRegion, ulong size) { size += default(AllocationEntry).CodegenTypeSize(); var allocator = sharedConfigMemoryRegion.Allocator; if (allocator.FreeOffset + size >= sharedConfigMemoryRegion.MemoryHeader.MemoryRegionSize) { throw new OutOfMemoryException(); } // Update the address. // uint offset = allocator.FreeOffset; // Update memory region properties. // allocator.FreeOffset += (uint)Utils.Align(size, 64); allocator.AllocationCount++; // Update last allocated entry. // if (allocator.LastAllocatedOffset != 0) { AllocationEntry lastAllocationEntry = new AllocationEntry() { Buffer = sharedConfigMemoryRegion.Buffer + (int)allocator.LastAllocatedOffset }; lastAllocationEntry.NextEntryOffset = offset; } // Update current allocated entry. // AllocationEntry allocationEntry = new AllocationEntry() { Buffer = sharedConfigMemoryRegion.Buffer + (int)offset }; allocationEntry.PrevEntryoffset = allocator.LastAllocatedOffset; allocator.LastAllocatedOffset = offset; return(allocationEntry); }
/// <summary> /// Add a new shared config. /// </summary> /// <typeparam name="TProbingPolicy">HashTable lookup policy.</typeparam> /// <typeparam name="TType">Codegen config type.</typeparam> /// <typeparam name="TProxy">Codegen proxy type.</typeparam> /// <param name="sharedConfigMemoryRegion"></param> /// <param name="componentConfig"></param> public static void Add <TProbingPolicy, TType, TProxy>( this SharedConfigMemoryRegion sharedConfigMemoryRegion, ComponentConfig <TType, TProxy> componentConfig) where TProbingPolicy : IProbingPolicy where TType : ICodegenType, new() where TProxy : ICodegenProxy <TType, TProxy>, new() { uint slotIndex = 0; SharedConfig <TProxy> sharedConfig = sharedConfigMemoryRegion.Get <TProbingPolicy, TProxy>(componentConfig.Config, ref slotIndex); if (sharedConfig.Buffer != IntPtr.Zero) { throw new ArgumentException("Config already present", nameof(componentConfig)); } TType config = componentConfig.Config; // Calculate size to allocate. // sharedConfig = sharedConfigMemoryRegion.Allocate <SharedConfig <TProxy> >(); // Update hash map // ProxyArray <uint> sharedConfigOffsets = sharedConfigMemoryRegion.ConfigsOffsetArray.Elements; sharedConfigOffsets[(int)slotIndex] = (uint)sharedConfig.Buffer.Offset(sharedConfigMemoryRegion.Buffer); // Copy header, copy config. // SharedConfigHeader sharedHeader = sharedConfig.Header; TProxy configProxy = sharedConfig.Config; // Initialize header. // sharedHeader.ConfigId.Store(1); sharedHeader.CodegenTypeIndex = config.CodegenTypeIndex(); // Copy the config to proxy. // CodegenTypeExtensions.Serialize(componentConfig.Config, sharedConfig.Config.Buffer); }
public void Insert() { using var sharedMemoryRegionView = SharedMemoryRegionView.Create <MlosProxyInternal.SharedConfigMemoryRegion>(SharedMemoryMapName, SharedMemorySize); sharedMemoryRegionView.CleanupOnClose = true; MlosProxyInternal.SharedConfigMemoryRegion sharedConfigMemoryRegion = sharedMemoryRegionView.MemoryRegion(); var hashTable = new SharedConfigManager(); hashTable.SetMemoryRegion(sharedConfigMemoryRegion); for (int i = 0; i < 500; i++) { { TestComponentConfig config = default; config.ComponentType = (uint)(i + 1); config.Category = 2; config.Delay = 5; var componentConfig = ComponentConfig.Create(config); hashTable.Insert(componentConfig); } { var componentConfig = new ComponentConfig <TestComponentConfig, UnitTestProxy.TestComponentConfig>(); componentConfig.Config.ComponentType = (uint)(i + 1); componentConfig.Config.Category = 2; hashTable.UpdateConfig(componentConfig); Assert.Equal <double>(5, componentConfig.Config.Delay); } { var componentConfig = new ComponentConfig <TestComponentStatistics, UnitTestProxy.TestComponentStatistics>(); componentConfig.Config.Id = i; componentConfig.Config.RefCount.Value = 5; componentConfig.Config.Counters[0].Value = 2; hashTable.Insert(componentConfig); } } for (int i = 0; i < 500; i++) { { var componentConfig = new ComponentConfig <TestComponentConfig, UnitTestProxy.TestComponentConfig>(); componentConfig.Config.ComponentType = (uint)(i + 1); componentConfig.Config.Category = 2; hashTable.UpdateConfig(componentConfig); Assert.Equal <double>(5, componentConfig.Config.Delay); } { var componentConfig = new ComponentConfig <TestComponentStatistics, UnitTestProxy.TestComponentStatistics>(); componentConfig.Config.Id = i; hashTable.UpdateConfig(componentConfig); Assert.Equal <ulong>(5, componentConfig.Config.RefCount.Value); Assert.Equal <ulong>(2, componentConfig.Config.Counters[0].Value); } { var componentStatistics = new TestComponentStatistics() { Id = i }; SharedConfig <UnitTestProxy.TestComponentStatistics> sharedConfig = hashTable.Lookup(componentStatistics); } { TestComponentStatistics.CodegenKey codegenKey = default; codegenKey.Id = i; SharedConfig <UnitTestProxy.TestComponentStatistics> sharedConfig = hashTable.Lookup(codegenKey); Assert.Equal <ulong>(5, sharedConfig.Config.RefCount.Load()); Assert.Equal <ulong>(2, sharedConfig.Config.Counters[0].Load()); } } }
public void SetMemoryRegion(MlosProxyInternal.SharedConfigMemoryRegion sharedConfigMemoryRegion) { this.sharedConfigMemoryRegion = sharedConfigMemoryRegion; }