Ejemplo n.º 1
0
        public void Initialize()
        {
            if (_isInitialized)
            {
                DisposeRuntime();
            }
            _isInitialized = true;

            // Check limits
            if (_outputInitializer.Count > ushort.MaxValue * Tools.NB_BITS_PER_BYTE) // To increase this limit change ushort type of maskLength and index into PulseSource
            {
                throw new OverflowException($"Max output capacity reached: Max={sizeof(ushort) * Tools.NB_BITS_PER_BYTE} NbOutputs={_outputInitializer.Count}");
            }

            // First prepare indices
            PrepareIndices(_outputInitializer, _inputInitializer);

            // Compute the memory length.

            // 1. We use 1 bit to flag a subscribe
            var flagsSize = Ceiling(_outputInitializer.Count / Tools.NB_BITS_PER_BYTE, sizeof(uint));

            // 2. For subscribers
            // 2.1 state size
            var pulseProbeSize = sizeof(PulseProbe) * _outputInitializer.Count;

            // 3. For producer
            // 3.1 structure layout size
            var pulseSourceSize = sizeof(PulseSource) * _inputInitializer.Count;
            // 3.2 pImpulseMask size
            var pulseMasksSizes = _inputInitializer.Sum(p => p.Value.MaskLength);

            var totalSize = flagsSize + pulseProbeSize + pulseSourceSize + pulseMasksSizes;

            // Allocate the memory
            _globalMemory = Marshal.AllocHGlobal(totalSize);

            // Prepare memory
            var ptr = (byte *)_globalMemory;

            //var pFlags = ptr;
            //var pPulseProbe = (PulseProbe*)(ptr + coilSize);
            //var pPulseMetrics = (PulseMetrics*)(ptr + coilSize + galvanometersSize);
            //var pPulseSource = (PulseSource*)(ptr + coilSize + galvanometersSize + galvanometerStatesSize);
            //var pPulseMask = ptr + coilSize + galvanometersSize + galvanometerStatesSize + currentFlowsSize;

            var pPulseSource = (PulseSource *)ptr;
            var pFlags       = ptr + pulseSourceSize;
            var pPulseMask   = ptr + pulseSourceSize + flagsSize;
            var pPulseProbe  = (PulseProbe *)(ptr + pulseSourceSize + flagsSize + pulseMasksSizes);

            InstallFlags(pFlags, flagsSize);
            InstallPulseProbes(pPulseProbe, pFlags, _outputInitializer);
            InstallPulseSources(pPulseSource, pFlags, pPulseMask, _inputInitializer);

            _runTimes.AddRange(_inputInitializer.Select(p => p.Value.CreateRuntime()));
            _queue.SetCapacity(_runTimes.Count);
            _queue.Reset();

            #region Build Report
            _reports.Clear();
            _reports.AppendLine("=== Initialize");
            _reports.AppendLine($"Flags         Size: {flagsSize / 1000.0} Ko");
            _reports.AppendLine($"PulseProbe    Size: {pulseProbeSize / 1000.0} Ko");
            _reports.AppendLine($"PulseSource   Size: {pulseSourceSize / 1000.0} Ko");
            _reports.AppendLine($"PulseMasks    Size: {pulseMasksSizes / 1000.0} Ko");
            _reports.AppendLine("--------------------------------");
            _reports.AppendLine($"Total         Size: {totalSize / 1000.0} Ko");
            _reports.AppendLine("===");
            #endregion
        }