15

Insanely obscure pthread api for thread priority not only outlandishly incomprehensible, but also it just doesn't work on android.

So, is there a way for me to reduce or increase a thread's priority?

int currentPolicy;
struct sched_param sched;
status = pthread_getschedparam(pthread_self(), &currentPolicy, &sched);
printf("sched.sched_priority:%d currentPolicy:%d", sched.sched_priority, currentPolicy);
printf("priority min/max:%d/%d", sched_get_priority_min(currentPolicy), sched_get_priority_max(currentPolicy));

outputs:

sched.sched_priority:0 currentPolicy:0

priority min/max:0/0

Also, no matter what I do, pthread_setschedparam always return an error for me (Invalid argument). In my code, I need to reduce priority of my handler thread to make sure that the other thread uses more cpu time. Or, alternatively, I could boost thread priority of my other thread that I want to use as more cpu compared to other threads in my process.

Is there any way for me to do that? I use native c++ code only.

Edit: From this post looks like android's threads are some kind of light weight processes and to modify priorities for them setpriority should be used. It looks that the function works (getpriority before and after indicates that priority was modified). However, I don't see expected effect in my app.

Community
  • 1
  • 1
Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • "*... pthread_setschedparam always return an error for me (Invalid argument).*", so would you mind showing us what you did pass into the function to have it return `EINVAL`? – alk Jul 01 '13 at 08:13
  • for currentPolicy I tried to pass all available values (0, 1, 2, 3). For sched.sched_priority I tried to set different value (-10, 10 etc). All fail. – Pavel P Jul 01 '13 at 19:57

3 Answers3

10

Android threads are Linux threads. Nothing special about them.

setpriority() alters the thread's "nice" value, which affects the priority at which the thread is scheduled.

pthread_setschedparam() can be used to change the policy as well.

Generally speaking, you can't raise the priority or change its policy without elevated privileges (CAP_SYS_NICE). You can lower it, or raise it back to "normal" priority.

If you use adb shell ps -t -p you can see the priorities assigned to every thread. This information is also included in Dalvik stack dumps.

Dalvik uses setpriority() to temporarily raise the GC thread's priority if necessary (to avoid priority inversion). If you look at this bit of code around line 625 you can see it. You can also see the call to set_sched_policy(), an Android library function that changes which cgroup the thread is in.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • 2
    That's close. `nice(int)` should be used on android which uses setpriority. Everything else just doesn't work. I also tried to search entire android source code and other functions aren't used. – Pavel P Jul 01 '13 at 20:03
10

Here's simple answer: use int nice(int increment). It's declared in unistd.h

here's the code of the function from Android:

int nice(int increment)
{
    int  priority = getpriority(PRIO_PROCESS, 0);
    return setpriority( PRIO_PROCESS, 0, priority+increment);
}

so, setpriority can be used to set thread priority.

I actually got difference as expected in my code by using nice(-10) or nice(10)

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • 1
    where should I place this code ? is it for threads or the process ? also, what is the return value ? thanks – RonTLV Jan 28 '18 at 14:14
  • FWIW looks like this is declared in `` – nmr Feb 02 '18 at 20:02
  • @nmr 5 years ago it might not have been the case – Pavel P Feb 03 '18 at 01:13
  • So, you mean, either `nice()` or `setpriority()` can be used? Also, is there any way for a user-level application to alter sched_priority other than SCHED_OTHER on a non-rooted Android device? I don't think so but just asking. – Jenix Sep 25 '19 at 23:52
  • In your original question, about `setpriority()`, you said "However, I don't see expected effect in my app", and then you wrote your own answer like this.. With `setpriority()`, did you actually see any difference or not? – Jenix Sep 26 '19 at 00:01
  • 1
    @Jenix I don't know what I meant 6 years ago :) Perhaps I didn't use `setpriority` correctly. My own answer shows what works on android. – Pavel P Sep 26 '19 at 08:50
  • This won't set the priority of the current thread, but the current process. – Constantin Geier May 12 '20 at 13:33
  • @ConstantinGeier The Linux implementation of `setpriority` differs from the POSIX standard, specifically `setpriority` sets the _thread_ priority, not the entire process priority. This is called out in the "Bugs" section of the Linux man pages: https://linux.die.net/man/2/setpriority I've also verified this behavior by giving different threads different priorities via `setpriority` on Android and observing the results with `adb shell ps -T -p -l` – jocopa3 Oct 19 '22 at 11:42
1

There is no way to set the priority of a POSIX thread in Android. The nice() and setpriority() functions configure the priority of a process, not of a single thread.

corro
  • 343
  • 3
  • 15
  • 1
    that incorrect, i have verified it myself. nice & set-priority(default) apply to current process which in android native world a linux LWP. your confusion may be stemming from fact that the priorities are inhereted by all launched threads. so if you set prio before launching child/worker threads the'll all have that prio. – voidStar Jan 15 '14 at 20:23
  • Buy that does not mean you can change the policy/priority of a given thread after it is created/running. – Remy Lebeau Jun 02 '14 at 21:33
  • I agree. There is no way to set the priority of ndk thread(s). Calling setpriority() with PRIO_PROCESS changes some priority (yet unknown to me which exactly) but In a simple test I created 2 std::thread and was calling setpriority() with different priorities in them - they alternating set the priority of themself and its coaleque. – Constantin Geier May 12 '20 at 13:31
  • The Linux implementation of `setpriority` differs from the POSIX standard; it changes the thread priority instead of the process priority. This difference is called out in the "Bugs" section of the Linux man pages: https://linux.die.net/man/2/setpriority I also tested this by creating multiple `std::thread`'s, using `pthread_gettid_np` to convert their `native_handle()` to a thread id, setting different priorities via `setpriority`, and verifying the results by looking at the NI and PRI columns of `adb shell ps -T -p -l`. My priority changes were applied per-thread, not process-wide – jocopa3 Oct 19 '22 at 11:59