2

My Android app is currently in open beta and I am receiving crash reports from my beloved testers. Audio processing is the app's primary focus therefore the render thread is cpu intensive and time sensitive. In an attempt to achieve the best performance possible, I am reserving exclusive cores for the process by calling:

int exclusiveCores[] = {};

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        exclusiveCores = android.os.Process.getExclusiveCores();
}

then sending the int array on through the JNI to be handled by the engine.

This has worked fine until recently when I received a crash report stating a RuntimeException was thrown on the getExclusiveCores() call. The device was a Samsung J7 (SM-J727T) running Android 7.0. This is the only device so far that has given me this report.

Has anyone else experienced this issue? Is this API not available for this specific device? Is there another limitation I should be checking for before calling getExclusiveCores?

The documentation states:

To support an exclusive core on a device:

Enable cpusets and configure a cpuset that contains only the top foreground application.

Ensure one core (this is the exclusive core) is reserved for threads from this cpuset.

but I am unable to find any other documentation on how to enable cpusets and configure a cpuset.

Can anyone provide an example of this implementation or point me in the right direction?

Also, I personally do not have this device and Firebase Testlab does not have this device running android 7.0 so testing any solution will have its own complications.

Thanks

Community
  • 1
  • 1
foolioJones
  • 667
  • 5
  • 10
  • Just curious..(Have not used getExclusiveCores(), so haven't experienced the issue). Samsung tends to have it's particularities depending device and ROM. However, I wonder if you want to achieve better scheduling and priority for audio, why don't you use opensl_es recording or playback thread. You could do your processing in any of the callbacks (they run in their own high priority thread), if opensl_es is setup correctly you should get a fast track thead (FIFO with low nice) for callback. If you only do playback you can send first buffer from standard thread and follow up on playback thread. – alexm Feb 27 '18 at 17:26
  • ...of course, be careful not to block the thread or you may get glitches. Hope it helps. – alexm Feb 27 '18 at 17:28
  • Thanks for your comment. My engine is using open sl but according to the fine people in android audio department, there are a few additional techniques to improve its performance. One of which is setting thread affinity which is why I am making to call to get exclusive cores. – foolioJones Mar 01 '18 at 08:27
  • OK, that makes sense to me, as long as you are doing expensive processing which would definitely block a fast track thread and create a new one. AFAIK, when you setup OpenSL_ES you pass through a callback for the OnCompletition event, OpenSL_ES creates it's own private threads(for IO), again if OpenSL_ES is well setup, you get a FIFO scheduling with high priority for that thread (would beat any user space thread, taking into account that you cannot change sched policy or increase priority of user created threads), so I don't think you can set thread affinity to that private thread. – alexm Mar 01 '18 at 11:18

1 Answers1

1

I also ran into this on a Samsung Galaxy S6 running Android 7.0.

Unfortunately it looks like getExclusiveCores isn't implemented on some devices (despite being a mandatory API, specified in the Android CDD).

The best advice is to wrap calls to this method in a try/catch block and catch the RuntimeException:

try {
    exclusiveCores = android.os.Process.getExclusiveCores();
} catch (RuntimeException e){
    Log.w(TAG, "getExclusiveCores() is not supported on this device.");
}
donturner
  • 17,867
  • 8
  • 59
  • 81