Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread priority - 'unit test'

A very concise question: How do I prove with a simple test, that setting:

android.os.Process.setThreadPriority(int); 

actually works?

The reason I post this question is mainly generic, as I can't find a simple test that I can replicate.

Further reading:

It is important to me and my application specifically, as it captures audio, which must be the priority. The audio data is also written to a file as well as being analysed for its properties, which is of less importance - Therefore I don't require these tasks to be 'truly simultaneous'.

In my audio thread, I set:

Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO);

I can simply test the above has 'applied' by checking before and after:

Process.getThreadPriority(Process.myTid());

However, my need for a test is due to the documentation, which states:

Standard priority of the most important audio threads. Applications can not normally change to this priority.

Despite the log output showing the priority changed to -19, my concern, raised by the wording in the documentation, is that the System may not allow a value of -19 for a normal application at the time of execution and it is possibly reserved for System applications only?

If the above is true, I wonder how I could simply prove what happens to this priority value - Is it defaulted to the maximum permitted, or could it be ignored completely?

In regards to the actual test itself, I've experimented with loops and pauses, but without success and I don't trust the results of the attempts I've made. I'm also aware that the behaviour is OS dependent, so perhaps I cannot replicate a stand-alone Java test of which I've failed to find any upvoted examples?

Hope someone can help. Thanks in advance.

EDIT - Further to the initial answers, I do appreciate that the behaviour may not be what I want or expect. I'd like the actual physical test of this please, rather than an explanation of possibilities.

The test would consist of multiple threads running with different priorities and the order they complete in printed out to the log, nothing more complex than that. My attempts were seemingly over-complex, hence I'm asking for assistance here.

like image 220
brandall Avatar asked Jun 24 '16 11:06

brandall


People also ask

How do you find the priority of a thread?

The getPriority() method of thread class is used to check the priority of the thread. When we create a thread, it has some priority assigned to it. Priority of thread can either be assigned by the JVM or by the programmer explicitly while creating the thread. The thread's priority is in the range of 1 to 10.

How is thread priority assigned?

In multi-threaded applications, each thread is assigned with a priority. The processor is assigned to the thread by the thread scheduler based on its priority i.e. the highest priority thread is assigned the processor first and so on. The default priority of a thread with a value of '5'.

What is the normal priority of the thread?

Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and the value of MAX_PRIORITY is 10.

What is minimum thread priority?

The minimum thread priority in java is 1 and maximum or highest thread priority is 10. We will see a program example to set and get thread priority. Default priority of thread in java is = 5.


2 Answers

Answer: You can't. If the test you're looking for works, it's not simple. If the test you want is simple, it can't work.

Android is not considered a "real-time" operating system, where guarantees about priority are hard (i.e. guaranteed and reliable) rather than soft (i.e. advisory and only largely honored). In a RT O/S, you could write a simple test that evaluated a race condition with one high priority thread and one low priority thread, and this test would evaluate deterministically. On a non-real-time OS, you'll only get a statistical guarantee. And that means you need a statistical test, which doesn't pass the criterion of simple. A statistical test, however, can be generic. Write a test harness that runs a test N times and passes the test based on some threshold value less than N.

But even setting up a base test isn't simple. As a rule, scheduling priority only matters when the machine is running at load, that is, when there's not enough CPU to go around. So to set up your test, you need to be running something that will swamp the CPU; you might as well mine bitcoin to make sure your process is running. In case this isn't obvious, count mining attempts rather than successes. Beware of voluntarily yielding to the OS too easily (wait calls) and operations that can optimized out by the compiler (simple loops).

Once you've set up your base load, you can then set your high-priority thread. It also needs to actually do something in order to verify that it's running at high priority, so you might as well mine bitcoin in this thread as well. If this thread is running at higher priority, you should get a higher count for some given duration in the higher priority thread over the lower one.

But you might not. Since you're not on a RT OS, you'll only get higher counts (presumably) most of the time. If the duration is too small, you'll be subject to the typical duration of the scheduler. So you'll likely need to do some experimentation to determine what minimum duration yields something of consistent answers.

This kind of experimentation is not simple. You're not on a RT OS, so what priority means is very fuzzy. It's (almost certainly) not documented, and so the meaning of the priority numbers is arbitrary. How the scheduler uses these priority numbers is whatever they want. There may be magic thresholds, for example. If there's a priority that means "never interrupt; only wait for a yield" and you run a process that doesn't yield, you'll hang the machine. Since these priority numbers can mean anything, you'll need to find out something of what they mean in practice in order to make your tests meaningful.

All this should be a hint about why there's a market for embedded real-time operating systems. Sometimes you need timing guarantees, and when you do, you should not use a non-real-time OS, even if it's tempting.

like image 54
eh9 Avatar answered Sep 21 '22 18:09

eh9


What is being tested

The CPU you are running on, has multiple computing units (cores), which can run in parallel.

The operating system has scheduling points (quanta), where it will switch tasks, choosing (through some arcane logic the best threads to execute next.

The operating system has asynchronous resource access. When trying to read from an external device it may :-

  1. Issue a request
  2. Schedule a different thread
  3. Restart the thread after the data is available (possibly immediately, maybe after a quantum expires).

Java the language environment may have further abstractions.

How do I prove with a simple test, that setting: android.os.Process.setThreadPriority(int); actually works?

In order to identify that more processing occurs on the higher priority thread, you need to :-

  1. Ensure that the machine has all its CPU resources tied up.
  2. Ensure that the thing you are testing does not require external asynchronous devices.
  3. Ensure that the test lasts multiple quanta.

Ensure the CPU is tied up

If there are spare CPUs, then code which wants to run, can and will. So the result of tests would show marginal difference between the thread priority, because it didn't matter.

Ensure the test does not require asynchronous IO

If you require writing to a device, the gap for this time would cause you to be driven by the speed of the IO device rather than the thread priority.

Ensure the tests has multiple quanta

The thread priority effects the decision about which thread to schedule next. Given that a thread once executed runs for the whole quanta, and then another schedule decision is made, then the test needs to test multiple of these decisions.

Can thread priority make a difference ?

As Android makes no claims to be a real-time OS, then there is no guarantee, that a thread will have a maximum wait time of X. (The guarantee offered by a real-time OS). However, if a thread is ready to execute (not waiting for devices, or other asynchronous events), then the likelihood is that a high priority thread will start executing in the next quantum.

like image 43
mksteve Avatar answered Sep 21 '22 18:09

mksteve