private static unsafe void SetMaxCpuRate(Win32Job job, SessionSettings session, ulong systemAffinityMask) { if (session.CpuMaxRate > 0) { // Set CpuRate to a percentage times 100. For example, to let the job use 20% of the CPU, // set CpuRate to 20 times 100, or 2,000. uint finalCpuRate = session.CpuMaxRate * 100; // CPU rate is set for the whole system so includes all the logical CPUs. When // we have the CPU affinity set, we will divide the rate accordingly. if (session.CpuAffinityMask != 0) { ulong affinity = systemAffinityMask & session.CpuAffinityMask; uint numberOfSelectedCores = 0; for (int i = 0; i < sizeof(ulong) * 8; i++) { numberOfSelectedCores += (affinity & (1UL << i)) == 0 ? 0u : 1u; } Debug.Assert(numberOfSelectedCores < Environment.ProcessorCount); finalCpuRate /= ((uint)Environment.ProcessorCount / numberOfSelectedCores); } // configure CPU rate limit var limitInfo = new JOBOBJECT_CPU_RATE_CONTROL_INFORMATION { ControlFlags = JOB_OBJECT_CPU_RATE_CONTROL.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | JOB_OBJECT_CPU_RATE_CONTROL.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP, Anonymous = new JOBOBJECT_CPU_RATE_CONTROL_INFORMATION._Anonymous_e__Union { CpuRate = finalCpuRate } }; var size = (uint)Marshal.SizeOf(limitInfo); CheckWin32Result(PInvoke.SetInformationJobObject(job.JobHandle, JOBOBJECTINFOCLASS.JobObjectCpuRateControlInformation, &limitInfo, size)); } }
internal static extern bool QueryInformationJobObject(SafeJobObjectHandle hJob, JobObjectInformationClass JobObjectInfoClass, [Out] out JOBOBJECT_CPU_RATE_CONTROL_INFORMATION lpJobObjectInfo, int cbJobObjectInfoLength, IntPtr lpReturnLength);
internal static extern bool SetInformationJobObject(SafeJobObjectHandle hJob, JobObjectInformationClass JobObjectInfoClass, [In] ref JOBOBJECT_CPU_RATE_CONTROL_INFORMATION lpJobObjectInfo, int cbJobObjectInfoLength);