Scheduling fore- and background tasks

17 views
Skip to first unread message

Markus Junginger

unread,
Mar 27, 2009, 8:05:40 AM3/27/09
to android-platform
There's currently a discussion about this topic in the developers
group:
http://groups.google.com/group/android-developers/browse_thread/thread/1952712754139019

But it seems more like a platform issue, so let's start a thread here.

The problem is that background apps can dramatically affect the
foreground app. This is huge problem for games and other media apps
that rely on a constant and high frame rate, because it can totally
destroy the user experience. Imho, this is a key issue to solve before
Android can establish itself as a solid gaming platform like the
iPhone could.

I continue with what I wrote in the developer's group thread:
"So, my first thought on how to solve this is a guaranteed CPU slice
for the foreground app. Let the foreground task constantly get 90-95%
of the CPU time if it needs it, no matter what's running in the
background. The remaining 5-10% should be enough for background tasks.
I think that's perfectly fine if, for example, emails are received a
little slower when the user plays a game. Of course, if the foreground
task does not use the CPU entirely, background tasks should be able to
get a bigger slice.

Oh, and by the way, what about a JIT or a hotspot compiler? If Android
apps would be running a factor ~10 the problem would be smaller by the
same factor. :) "

Dianne Hackborn

unread,
Mar 27, 2009, 12:47:22 PM3/27/09
to android-...@googlegroups.com
Thank-you for moving this here. :)

As I said early in the other thread, yes we need to do better about forcing background apps to be scheduled at a lower priority, and there has been some work along those lines done already.  This is almost entirely a kernel issue -- the activity manager knows very well which apps are background and which are foreground, so given some kernel API to tell the scheduler about them, it is trivial to take care of this in the framework.

As far as having a JIT, I am pretty sure Dan has already addressed that before.  Personally I think for games the NDK is probably more appropriate.
--
Dianne Hackborn
Android framework engineer
hac...@android.com

Note: please don't send private questions to me, as I don't have time to provide private support.  All such questions should be posted on public forums, where I and others can see and answer them.

Markus Junginger

unread,
Mar 27, 2009, 1:55:01 PM3/27/09
to android-platform


On Mar 27, 5:47 pm, Dianne Hackborn <hack...@android.com> wrote:
> Thank-you for moving this here. :)
>
> As I said early in the other thread, yes we need to do better about forcing
> background apps to be scheduled at a lower priority, and there has been some
> work along those lines done already. This is almost entirely a kernel issue
> -- the activity manager knows very well which apps are background and which
> are foreground, so given some kernel API to tell the scheduler about them,
> it is trivial to take care of this in the framework.

Sounds good. :) So the game developers can just relax and wait for one
of the next updates? Is there a roadmap you can share with us?

> As far as having a JIT, I am pretty sure Dan has already addressed that
> before.  Personally I think for games the NDK is probably more appropriate.
Are there any news regarding a JIT compiler? Sorry, I probably missed
what Dan addressed here.

Given a better task scheduling, I agree it's possible to write good
games today. Still, Dalvik reminds me of Suns's VM from Java 1.0/1.1
(http://developer.android.com/guide/practices/design/
performance.html). ;)

blindfold

unread,
Mar 28, 2009, 11:32:04 AM3/28/09
to android-platform
> Are there any news regarding a JIT compiler?

Not that I know of. I've postponed further work with Android because
the lack of a JIT compiler has become a real showstopper. The very
same optimized algorithms that meet real-time constraints under Java
ME on run-of-the-mill Nokia phones unfortunately do not come close
under Android on the G1. I have not read any announcement that a JIT
compiler for Android will become available.

Regards

Eric Friesen

unread,
Mar 29, 2009, 2:52:25 PM3/29/09
to android-platform
What about something at the public API level. Where a background
service that is checking for email every 2 minutes. Wakes up and can
see this system wide setting that processing needs to be conserved for
the current user experience. Kind of like a wake lock, but more like a
processing power lock. Apps area already designed in the area of
memory management, to be frozen and unfrozen. Why not also include in
the API how to place nice on a CPU time level?

The way I see it, there might be two slightly different scenarios for
this:

1) The user has just opened their phone to SMS a friend. They are
smoothly scrolling through their list of contacts. If the background
service checks for email, the scrolling will become jerky. In this
situation the SMS will be sent and the phone will be idle very
shortly. So the ideal outcome might be just that the service sleeps
for a bit.

2) The user has been playing a game for 30 minutes. In this situation
maybe the email client reverts to checking email every 10 minutes, or
some other user supplied setting. Or perhaps doesn't check at all
depending on how the service author wants to write the service.

Certainly some effort would need to be in place to help encourage
service authors to completely ignore this. Adding examples to the SDK
and documentation. Thus combined with kernel process scheduling and
priorities, processing that doesn't really need to happen at all
doesn't happen at all, and the background stuff that is still vital
happens but at a lower priority.

-E

On Mar 27, 9:47 am, Dianne Hackborn <hack...@android.com> wrote:
> Thank-you for moving this here. :)
>
> As I said early in the other thread, yes we need to do better about forcing
> background apps to be scheduled at a lower priority, and there has been some
> work along those lines done already.  This is almost entirely a kernel issue
> -- the activity manager knows very well which apps are background and which
> are foreground, so given some kernel API to tell the scheduler about them,
> it is trivial to take care of this in the framework.
>
> As far as having a JIT, I am pretty sure Dan has already addressed that
> before.  Personally I think for games the NDK is probably more appropriate.
>
> On Fri, Mar 27, 2009 at 5:05 AM, Markus Junginger <mar...@junginger.biz>wrote:
>
>
>
>
>
>
>
> > There's currently a discussion about this topic in the developers
> > group:
>
> >http://groups.google.com/group/android-developers/browse_thread/threa...
>
> > But it seems more like a platform issue, so let's start a thread here.
>
> > The problem is that background apps can dramatically affect the
> > foreground app. This is huge problem for games and other media apps
> > that rely on a constant and high frame rate, because it can totally
> > destroy the user experience. Imho, this is a key issue to solve before
> > Android can establish itself as a solid gaming platform like the
> > iPhone could.
>
> > I continue with what I wrote in the developer's group thread:
> > "So, my first thought on how to solve this is a guaranteed CPU slice
> > for the foreground app. Let the foreground task constantly get 90-95%
> > of the CPU time if it needs it, no matter what's running in the
> > background. The remaining 5-10% should be enough for background tasks.
> > I think that's perfectly fine if, for example, emails are received a
> > little slower when the user plays a game. Of course, if the foreground
> > task does not use the CPU entirely, background tasks should be able to
> > get a bigger slice.
>
> > Oh, and by the way, what about a JIT or a hotspot compiler? If Android
> > apps would be running a factor ~10 the problem would be smaller by the
> > same factor. :) "
>
> --
> Dianne Hackborn
> Android framework engineer
> hack...@android.com

Mark Murphy

unread,
Mar 29, 2009, 3:35:48 PM3/29/09
to android-...@googlegroups.com
Eric Friesen wrote:
> 1) The user has just opened their phone to SMS a friend. They are
> smoothly scrolling through their list of contacts. If the background
> service checks for email, the scrolling will become jerky. In this
> situation the SMS will be sent and the phone will be idle very
> shortly. So the ideal outcome might be just that the service sleeps
> for a bit.

One way to do this would be through a "fuzzy" flag or value when setting
up an alarm in AlarmManager. Instead of a service saying "wake me up
every 5 minutes", it would say "wake me up every five-ish minutes" or
"wake me up in 5 minutes, but feel free to wait 3 more minutes if
needed". Depending on what's going on with the device, the OS could then
elect to delay certain alarms.

What we want is for AlarmManager to not raise alarms based on current
conditions. Once we fire the alarm, we're starting up the service again
(possibly starting a whole new process), and that will chew up some CPU
time.

> 2) The user has been playing a game for 30 minutes. In this situation
> maybe the email client reverts to checking email every 10 minutes, or
> some other user supplied setting. Or perhaps doesn't check at all
> depending on how the service author wants to write the service.

Here's one possible solution:

-- Add onBusyCPU() and onNormalCPU() methods that services could
override. Those might not be called simply for a scrolling list, but in
cases where a "game mode" activity is launched. The purpose would be to
allow services to quickly tailor their AlarmManager usage (e.g., cutting
back on alarms in onBusyCPU()) *before* the game gets underway.

-- Call onBusyCPU() when a "game mode" activity is launched for all
distinct services scheduled to be invoked via an alarm in the next hour.
That will require starting up each of those services (since they
probably aren't presently running). This will delay the start of the
game by a bit, depending on how many such services there are, but then
the game should run more smoothly.

-- Call onNormalCPU() after the "game mode" activity exits, for all
services for whom we called onBusyCPU().

> Certainly some effort would need to be in place to help encourage
> service authors to completely ignore this.

I think you're missing a "not" in that sentence. ;-)

What would be useful is if there were a way for AlarmManager to log all
alarms and have a screen, perhaps off of Settings, for the user to
review what's all going on in the background while they're playing the
game. Right now, there's no great way for users to have any idea who the
culprit is.

> Adding examples to the SDK and documentation.

That's the carrot. Users being able to positively identify who's causing
them grief, and giving appropriate feedback to problematic apps, is the
stick.

--
Mark Murphy (a Commons Guy)
http://commonsware.com | http://twitter.com/commonsguy

Android App Developer Books: http://commonsware.com/books.html

Eric Friesen

unread,
Mar 30, 2009, 1:46:06 PM3/30/09
to android-platform
I agree completely with Mark's comments.

Definitely AlarmManager is a great place to implement this kind of
thing. And I also agree that having some tool to view what services
are acting up frequently and eating up all the CPU cycles is a better
carrot than having good documentation and examples and pleading with
developers for best practices.

My only question left would be, is there any conceivable background
service that would want to pause what it is doing that should not be
using AlarmManager for it's scheduling? I would think so. Like perhaps
some kind of music player, or bit torrent client or something.
Something that would not be using the AlarmManager, but might
definitely want to scale down duties automatically for the user.
> Mark Murphy (a Commons Guy)http://commonsware.com|http://twitter.com/commonsguy

Jean-Baptiste Queru

unread,
Mar 30, 2009, 1:47:30 PM3/30/09
to android-...@googlegroups.com
I might be wrong, but I think there's a notion of imprecise alarms in
cupcake. I can't remember what the API would be called, though.

JBQ

--
Jean-Baptiste M. "JBQ" Queru
Android Engineer, Google.

Questions sent directly to me that have no reason for being private
will likely get ignored or forwarded to a public forum with no further
warning.

Mark Murphy

unread,
Mar 30, 2009, 2:21:03 PM3/30/09
to android-...@googlegroups.com
Jean-Baptiste Queru wrote:
> I might be wrong, but I think there's a notion of imprecise alarms in
> cupcake. I can't remember what the API would be called, though.

Looks like it is setInexactRepeating().

I'm a little nervous about the phase-aligned alarms possibly
exacerbating the foreground app problem. If the device is asleep,
phase-aligning the alarms is great. If the device is not asleep (e.g.,
playing a game), you may want to avoid phase-aligning, so the device
doesn't all of a sudden slow down at the top of the hour, for example.
This might be handled under the covers -- it's tough to tell from the API.

Thanks!

_The Busy Coder's Guide to Android Development_ Version 2.0 Available!

Dianne Hackborn

unread,
Mar 30, 2009, 2:23:20 PM3/30/09
to android-...@googlegroups.com
Whoa whoa.  Please, let's take a step back here.  As I said in the original discussion, I really think what we need to do first is get background scheduling working correctly.  I would be very opposed to introducing significant new APIs right now, which are basically working around the fact that we aren't being aggressive enough about scheduling the CPU usage of background vs. foreground processes.  My instinct is that fixing this will basically fix the problem that has been raised, without having to add new APIs that people need to use correctly, and a lot of complexity in the system to try to implement those APIs that are they are being defined (and which in user space are going to be basically impossible to implement in a robust way).

Basic rule of thumb: get this working as well as you can for the general case and only then go on to start introducing special cases for specific scenarios that still don't work well.  We are far from having background working really well at this point as a general case; it is too soon to through in specialized mechanisms for this.

So the first thing I would suggest for someone who really cares about this is to dig in to the kernal and improve things.  We actually already have some initial thought along these lines, using Linux scheduling classes to force all of the threads in a background process to be scheduled in a special way so that together they can take more than say 90% of the foreground threads' CPU.  We already have most of the information we need in the activity manager to decide what scheduling class a process should be in.

(In fact you can pretty much just look at the oom_adj information, though we'll probably want to do some small tuning of this to not count broadcast receivers or service interacts as foreground...  though doing this will also probably require some tuning of scheduling of broadcasts and stuff so that timeouts can be done correctly.  These are the nitty gritty details that will ultimately determine how well the solution really works for the case of someone who wants to be somewhat guaranteed a majority of the CPU at any time.)

Anyway, someone who actually wants to work on this should probably get involved on android-kernel, since most of the work here is related to the kernel.

And and as JBQ pointed out, we do already have fuzzy scheduling of alarms in Cupcake, though this was done for the purpose of batching alarms while a device is asleep, to reduce the amount of time it spends awake when multiple entities are running regular alarm intervals.

On Sun, Mar 29, 2009 at 12:35 PM, Mark Murphy <mmu...@commonsware.com> wrote:

--
Dianne Hackborn
Android framework engineer
hac...@android.com
Reply all
Reply to author
Forward
0 new messages