Ejemplo n.º 1
0
        void AssignProcessToJobObject()
        {
            var securityAttributes = new WinInterop.SecurityAttributes();

            securityAttributes.nLength = Marshal.SizeOf(securityAttributes);

            hJob = CheckResult(WinJobs.NativeMethods.CreateJobObject(securityAttributes, "procgov-" + Guid.NewGuid()));

            // create completion port
            hIOCP = CheckResult(WinJobs.NativeMethods.CreateIoCompletionPort(WinHandles.NativeMethods.INVALID_HANDLE_VALUE, IntPtr.Zero, IntPtr.Zero, 1));
            var assocInfo = new WinJobs.JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
                CompletionKey  = IntPtr.Zero,
                CompletionPort = hIOCP
            };
            uint size = (uint)Marshal.SizeOf(assocInfo);

            CheckResult(WinJobs.NativeMethods.SetInformationJobObject(hJob, WinJobs.JOBOBJECTINFOCLASS.AssociateCompletionPortInformation,
                                                                      ref assocInfo, size));

            // start listening thread
            listener = new Thread(CompletionPortListener);
            listener.Start(hIOCP);

            WinJobs.JobInformationLimitFlags flags = WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_BREAKAWAY_OK
                                                     | WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
            if (maxProcessMemory > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_PROCESS_MEMORY;
            }
            if (cpuAffinityMask != 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_AFFINITY;
            }

            long systemAffinity, processAffinity;

            CheckResult(WinProcesses.NativeMethods.GetProcessAffinityMask(hProcess, out processAffinity, out systemAffinity));

            // configure constraints
            var limitInfo = new WinJobs.JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
                BasicLimitInformation = new WinJobs.JOBOBJECT_BASIC_LIMIT_INFORMATION {
                    LimitFlags = flags,
                    Affinity   = systemAffinity & cpuAffinityMask
                },
                ProcessMemoryLimit = (UIntPtr)maxProcessMemory
            };

            size = (uint)Marshal.SizeOf(limitInfo);
            CheckResult(WinJobs.NativeMethods.SetInformationJobObject(hJob, WinJobs.JOBOBJECTINFOCLASS.ExtendedLimitInformation,
                                                                      ref limitInfo, size));

            // assign a process to a job to apply constraints
            CheckResult(WinJobs.NativeMethods.AssignProcessToJobObject(hJob, hProcess.DangerousGetHandle()));
        }
Ejemplo n.º 2
0
        void AssignProcessToJobObject()
        {
            var securityAttributes = new WinInterop.SecurityAttributes();

            securityAttributes.nLength = Marshal.SizeOf(securityAttributes);

            hJob = CheckResult(WinJobs.NativeMethods.CreateJobObject(securityAttributes, "procgov-" + Guid.NewGuid()));

            // create completion port
            hIOCP = CheckResult(WinJobs.NativeMethods.CreateIoCompletionPort(WinHandles.NativeMethods.INVALID_HANDLE_VALUE, IntPtr.Zero, IntPtr.Zero, 1));
            var assocInfo = new WinJobs.JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
                CompletionKey  = IntPtr.Zero,
                CompletionPort = hIOCP
            };
            uint size = (uint)Marshal.SizeOf(assocInfo);

            CheckResult(WinJobs.NativeMethods.SetInformationJobObject(hJob, WinJobs.JOBOBJECTINFOCLASS.AssociateCompletionPortInformation,
                                                                      ref assocInfo, size));

            WinJobs.JobInformationLimitFlags flags = 0;
            if (!propagateOnChildProcesses)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
            }
            if (maxProcessMemory > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_PROCESS_MEMORY;
            }
            if (cpuAffinityMask != 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_AFFINITY;
            }
            if (processUserTimeLimitInMilliseconds > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_PROCESS_TIME;
            }
            if (jobUserTimeLimitInMilliseconds > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_JOB_TIME;
            }

            long systemAffinity, processAffinity;

            CheckResult(WinProcesses.NativeMethods.GetProcessAffinityMask(hProcess, out processAffinity, out systemAffinity));

            // configure constraints
            var limitInfo = new WinJobs.JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
                BasicLimitInformation = new WinJobs.JOBOBJECT_BASIC_LIMIT_INFORMATION {
                    LimitFlags = flags,
                    Affinity   = systemAffinity & cpuAffinityMask,
                    PerProcessUserTimeLimit = 10_000 * processUserTimeLimitInMilliseconds, // in 100ns
                    PerJobUserTimeLimit     = 10_000 * jobUserTimeLimitInMilliseconds      // in 100ns
                },
Ejemplo n.º 3
0
        void AssignProcessToJobObject()
        {
            var securityAttributes = new WinInterop.SecurityAttributes();

            securityAttributes.nLength = Marshal.SizeOf(securityAttributes);

            hJob = CheckResult(WinJobs.NativeMethods.CreateJobObject(securityAttributes, "procgov-" + Guid.NewGuid()));

            // create completion port
            hIOCP = CheckResult(
                WinJobs.NativeMethods.CreateIoCompletionPort(WinHandles.NativeMethods.INVALID_HANDLE_VALUE, IntPtr.Zero,
                                                             IntPtr.Zero, 1));
            var assocInfo = new WinJobs.JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
                CompletionKey  = IntPtr.Zero,
                CompletionPort = hIOCP
            };
            uint size = (uint)Marshal.SizeOf(assocInfo);

            CheckResult(WinJobs.NativeMethods.SetInformationJobObject(hJob,
                                                                      WinJobs.JOBOBJECTINFOCLASS.JobObjectAssociateCompletionPortInformation,
                                                                      ref assocInfo, size));

            WinJobs.JobInformationLimitFlags flags = 0;
            if (!PropagateOnChildProcesses)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK;
            }

            if (MaxProcessMemory > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_PROCESS_MEMORY;
            }
            if (MaxWorkingSetSize > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_WORKINGSET;
            }

            if (ProcessUserTimeLimitInMilliseconds > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_PROCESS_TIME;
            }

            if (JobUserTimeLimitInMilliseconds > 0)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_JOB_TIME;
            }

            // only if NUMA node is not provided we will set the CPU affinity,
            // otherwise we will set the affinity on a selected NUMA node
            if (CpuAffinityMask != 0 && numaNode == 0xffff)
            {
                flags |= WinJobs.JobInformationLimitFlags.JOB_OBJECT_LIMIT_AFFINITY;
            }

            CheckResult(WinProcesses.NativeMethods.GetProcessAffinityMask(hProcess, out _, out var systemAffinityMask));

            if (flags != 0)
            {
                // configure basic constraints
                var limitInfo = new WinJobs.JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
                    BasicLimitInformation = new WinJobs.JOBOBJECT_BASIC_LIMIT_INFORMATION {
                        LimitFlags = flags,
                        Affinity   = systemAffinityMask & CpuAffinityMask,
                        PerProcessUserTimeLimit = 10_000 * ProcessUserTimeLimitInMilliseconds, // in 100ns
                        PerJobUserTimeLimit     = 10_000 * JobUserTimeLimitInMilliseconds,     // in 100ns
                        MaximumWorkingSetSize   = (UIntPtr)MaxWorkingSetSize,
                    },