Re: Suspend worker thread when in background

Eric Wing <[email protected]> Mon, 23 Jan 2017 10:03:31 -0800
Newsgroups gmane.comp.lib.sdl
Message-ID <CA+Q62MBTkTuO5eC98H1d31n8gU4NDoT-NhK5d4QemXVLNg0wWA@mail.gmail.com>
On 1/21/17, rtrussell <[email protected]> wrote:
>
> Eric Wing wrote:
>> To your original problem of suspending the thread: I say don’t suspend
>> your threads and just make them end. Design your threads so you tell them
>> to quit and you do a wait/join.
>
> I appreciate that in an ideal world this is preferable, but it's just not
> practical for me.  This is a port of an application with its roots going
> back 35 years and its codebase virtually unchanged for at least 15 years,
> and there's far too much state in the worker thread to hope to save it and
> then restore it again.  In any case, if my understanding is correct, there's
> no satisfactory way even of killing the thread asynchronously in Android so
> I'm no better off if in order to 'end' the thread it must poll some flag.
>


So we’re talking about Android here. Android will happily keep sucking
up CPU cycles and battery on your app’s background threads while
backgrounded. Worst case, you can just keep eating cycles.

But your worker threads don’t have a natural stopping point even when
there is no new incoming data/activity? You can’t add a flag to poll
at the end of their natural work to end the thread? So maybe they eat
some extra cycles for awhile after your app first backgrounds, but if
were talking at most a few dozen seconds, I doubt anybody will notice
or care.


In your case, Application exit is the edge case you need to worry
about. If it is a big problem, hacking in a kill thread may be a
reasonable option.


>
>> I’d actually like to write a new alternative SDLActivity some day that
>> keeps SDL on the main thread. This would require some changes on how
>> people deal with
>> the event loop
>
> This sounds like a great idea, so long as it doesn't hit performance
> (running in a separate thread can be advantageous if it means running on a
> separate CPU core).  Your frustration at the shortcomings of Android are
> clear and understandable, but it's not going to go away and we need to try
> to find workarounds like this.
>

It *shouldn't* affect performance. The OS scheduler should be doing
load balancing. The main UI thread (your app) shouldn't be doing much
of anything except supporting your app so those are CPU cycles you
need to spend anyway. More often than not, what I see is people
automatically assume more threads == more performance, but that's far
from the truth and often works against you. The main UI thread still
must deal with things like touch events. These things must be passed
to SDL, but now we have the complication of needing to communicate
safely between threads. I don't remember SDL's implementation, but
I've been in many other Android projects, and things like this usually
introduce either locking (which stalls both threads), or more async
which increases latency.

Careful utilization of threads can give you high performance (like for
chugging long pipelines of data). But simply adding random threads
when you aren't CPU bound to begin with, more often than not just
creates more sync points (locking) and unnecessary context switches.
If you need performance, you should be designing in how you want to
use threads to accomplish this.


And also, the Android garbage collector can assert itself and halt all
threads. I worked on a major app that kept hitting this problem,
killing the game's playability. Even though we were on a background
thread, we were affected by the GC constantly blocking all threads for
more than a couple of frames. I'm not sure if Android was actually
halting our native thread, or if it was just a result of something
making a system call calling into Java which had suspended all
threads.


>> So these variables remain at their previous value which can completely
>> break your application logic.
>
> I've read this before, but it's never affected me despite not coding
> defensively against it.  Whether I have simply been lucky I don't know, but
> I think I have seen comments to the effect that more recent versions of
> Android/SDL (I'm not sure which) don't suffer from this issue to the same
> degree.


This problem is an Android NDK behavior and not specific to SDL. It
still remains a problem and has not improved because Google considers
it a “performance feature” in that they do absolutely no work here.
Good libraries like SDL will clean up their global/static variables
and reinitialize them with their Quit/Init functions, but it presumes
that you called them correctly in your code. But there is a lot of
code (especially user code) that is not as meticulous as SDL in this
regard, and the complex application life-cycle of Android doesn’t
always make it easy to call quit/cleanup at the right time.



-Eric
_______________________________________________
SDL mailing list
[email protected]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org