Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Very simplified, it could work somehow like this:</p> <ol> <li>Create a periodic waitable timer with some reasonable small wait time (maybe 100ms). Get a "last" value for each relevant process by calling <code>GetProcessTimes</code> once.</li> <li>Loop forever, blocking on the timer.</li> <li>Each time you wake up: <ul> <li><strong>if</strong> <code>GetProcessAffinityMask</code> returns 0, call <code>SetProcessAffinityMask(old_value)</code>. This means we've suspended that process in our last iteration, we're now giving it a chance to run again. </li> <li><strong>else</strong> call <code>GetProcessTimes</code> to get the "current" value</li> <li>call <code>GetSystemTimeAsFileTime</code></li> <li>calculate delta by subtracting last from current</li> <li><code>cpu_usage = (deltaKernelTime + deltaUserTime) / (deltaTime)</code></li> <li><strong>if that's more than you want</strong> call <code>old_value = GetProcessAffinityMask</code> followed by <code>SetProcessAffinityMask(0)</code> which will take the process offline.</li> </ul></li> </ol> <p>This is basically a very primitive version of the scheduler that runs in the kernel, implemented in userland. It puts a process "to sleep" for a small amount of time if it has used more CPU time than what you deem right. A more sophisticated measurement maybe going over a second or 5 seconds would be possible (and probably desirable).</p> <p>You might be tempted to suspend all threads in the process instead. However, it is important <strong>not</strong> to fiddle with priorities and <strong>not</strong> to use <code>SuspendThread</code> unless you know exactly what a program is doing, as this can easily lead to deadlocks and other nasty side effects. Think for example of suspending a thread holding a critical section while another thread is still running and trying to acquire the same object. Or imagine your process gets swapped out in the middle of suspending a dozen threads, leaving half of them running and the other half dead.</p> <p>Setting the affinity mask to zero on the other hand simply means that from now on no single thread in the process gets any more time slices on any processor. Resetting the affinity gives -- atomically, at the same time -- all threads the possibility to run again.</p> <p>Unluckily, <code>SetProcessAffinityMask</code> does not return the old mask as <code>SetThreadAffinityMask</code> does, at least according to the documentation. Therefore an extra <code>Get...</code> call is necessary.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload