Example #1
0
        /// <summary>
        /// Adjust scheduling options.
        /// </summary>
        /// <param name="settings">The new scheduling options. </param>
        public void SetSchedulingOptions(MultiThreadSchedulingSettings settings)
        {
            if (_disposalComplete != null)
            {
                throw new ObjectDisposedException("Cannot set the number of threads for a disposed scheduler. ");
            }

            int numThreads;

            if ((settings.Mode & MultiThreadCreationMode.OneThreadPerLogicalCpu) != 0)
            {
                // FIXME filter this list based on process CPU affinity
                var cpuInfo = CpuTopologyInfo.GetList();

                if ((settings.Mode & MultiThreadCreationMode.OneThreadPerCpuCore) == MultiThreadCreationMode.OneThreadPerCpuCore)
                {
                    numThreads = CpuTopologyInfo.CountNumberOfCores(cpuInfo);
                }
                else
                {
                    numThreads = cpuInfo.Length;
                }

                settings.NumberOfThreads = numThreads;
            }
            else
            {
                numThreads = settings.NumberOfThreads;
                if (numThreads <= 0)
                {
                    throw new ArgumentOutOfRangeException($"{nameof(MultiThreadSchedulingSettings)}.{nameof(MultiThreadSchedulingSettings.NumberOfThreads)} is out of range: {numThreads}");
                }
            }

            // Cap at CPU quota, if requested.
            // FIXME For dynamic updates to CPU quota we should read the quota ourselves
            if ((settings.Mode & MultiThreadCreationMode.CapThreadsAtCpuQuota) != 0)
            {
                numThreads = Math.Min(numThreads, Environment.ProcessorCount);
            }

            if (numThreads == 0)
            {
                numThreads = 1;
            }

            SetNumberOfThreads(numThreads, settings.ThreadPriority);

            // Publish new options, if SetNumberOfThreads does not fail
            SchedulingOptions = settings;
        }
        private static CpuTopologyInfo[] Linux_GetList()
        {
            var cpuMask  = new BitMask(stackalloc ulong[512]);
            int cpuCount = 0;

            foreach (var fullDirName in Directory.EnumerateDirectories("/sys/devices/system/cpu/"))
            {
                if (Linux_IsSysFsCpuDirectory(fullDirName, out var cpuIdShort))
                {
                    cpuMask[cpuIdShort] = true;
                    cpuCount++;
                }
            }

            var infoArray = new CpuTopologyInfo[cpuCount];
            int cpuId     = -1;

            for (int i = 0; (cpuId = cpuMask.GetIndexOfNextOnBit(++cpuId)) >= 0; ++i)
            {
                infoArray[i] = Linux_ReadFromSysFsFile(cpuId);
            }

            return(infoArray);
        }