Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if the current thread has low I/O priority

Tags:

c++

io

winapi

if (reader.is_lazy()) goto tldr;

I have a background thread that does some I/O-intensive background type work. To please the other threads and processes running, I set the thread priority to "background mode" using SetThreadPriority, like this:

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN);

However, THREAD_MODE_BACKGROUND_BEGIN is only available in Windows Server 2008 or newer, as well as Windows Vista and newer, but the program needs to work well on Windows Server 2003 and XP as well. So the real code is more like this:

if (!SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)) {
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST);
}

The problem with this is that on Windows XP it will totally disrupt the system by using too much I/O. I have a plan for an ugly and shameful way of mitigating this problem, but that depends on me being able to determine if the current thread has low I/O priority or not.

Now, I know I can store which thread priority I ended up setting, but the control flow in the program is not really well suited for this. I would rather like to be able to test later whether or not the current thread has low I/O priority -- if it is in "background mode".

tldr:

GetThreadPriority does not seem to give me this information, it only gives the CPU priority.

Is there any way to determine if the current thread has low I/O priority?

like image 857
Magnus Hoff Avatar asked May 19 '10 08:05

Magnus Hoff


People also ask

What is set IO priority?

I/O priority queueing is used to control deferred I/O requests. If this function is invoked, all deferred I/O requests, except paging and swapping, will be queued according to the I/O priorities associated with the requesting address spaces. Paging and swapping are always handled at the highest priority.

How do I increase IO priority?

Using this API you can change the I/O priority. This API accepts a 'class' variable telling it what type of information about the process you want to change, that class variable must be set to ProcessIoPriority. You can then set the entire process's I/O priority in this manner.

How to set thread priority in c++?

Use the GetPriorityClass and SetPriorityClass functions to get and set the priority class of a process. Use the GetThreadPriority function to get the priority value of a thread.


1 Answers

Well it fails if you've already set it to background mode. Could you, dependent on whether you would like it to be background processing, not just Set the priority to background begin and see if it fails?

If you'd expect/want it not to be then you could test by calling background end.

If thats not good to you you'd probably be best off just using Thread Local Storage to store whether it is in background mode or not.


Edit by Magnus Hoff: This is how I ended up implementing it:

bool has_low_io_priority() {
    if (SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)) {
        // Seems we were able to enter background mode. That means we were
        // not in background mode from before.
        SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
        return false;
    } else {
        DWORD err = GetLastError();
        if (err == ERROR_THREAD_MODE_ALREADY_BACKGROUND) return true;
        else return false; //< Background mode is not available at all
    }
}

Works well :)

like image 146
Goz Avatar answered Sep 21 '22 17:09

Goz