After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 610830 - low priority task never executed if a high priority task is using all the CPU
low priority task never executed if a high priority task is using all the CPU
Status: RESOLVED WONTFIX
Product: glib
Classification: Platform
Component: mainloop
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2010-02-23 15:43 UTC by Philippe Normand
Modified: 2010-03-17 12:19 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
test case (996 bytes, text/plain)
2010-02-23 15:43 UTC, Philippe Normand
Details

Description Philippe Normand 2010-02-23 15:43:09 UTC
Created attachment 154505 [details]
test case

If the main loop has a high priority timeout function taking all CPU while it's running and a low priority function, the low priority function doesn't seem to get called, ever.

The attached test, when executed will always print "done", I couldn't see it print "low priority".
Comment 1 Sebastian Dröge (slomo) 2010-02-23 16:06:04 UTC
Yes, GLib should sometimes run lower-prio tasks too, even if there are still higher prio tasks pending. Starving the lower prio tasks is definitely not a good idea.
Comment 2 Benjamin Otte (Company) 2010-03-16 13:02:40 UTC
I don't think I agree. And the main loop docs clearly state that this is going to happen: "Events from high priority sources are always processed before events from lower priority sources."
The reason is quite simple: If you add some idle task it should be assumed it really is an _idle_ task, i.e. something that can be executed whenever there is time available and does not need to be executed at all. I'd imagine Gnumeric recomputing all cells, VMs running their GC, Abiword relayouting the whole document or the treeview recomputing sizes for invisible rows in an idle handler and those should not be executed while something important happens (like you pasting a lot of text into Gnumeric or Abiword).

That said, in a lot of cases it is useful to have tasks that increase their priority over time.
An example here is doing repaints while processing script timeouts in a browser: You don't want to redraw after every timeout (that roughly gets you 100 redraws/sec) but you want to redraw from time to time so users actually see stuff happening.

Currently one would need to register N different timeout sources with increasing priority and delay like so:
g_timeout_add_full (GDK_PRIORITY_REDRAW, 0, do_redraw, data, NULL);
g_timeout_add_full (G_PRIORITY_DEFAULT, 500, do_redraw, data, NULL);
g_timeout_add_full (G_PRIORITY_HIGH, 2000, do_redraw, data, NULL);
That would ensure that you likely get a redraw after 0.5s and definitely get one after 2s.

So I think it would be nice if we had an easy way to do achieve this. Not sure how to implement it though, I think the main loop code doesn't allow this easily.
Comment 3 Benjamin Otte (Company) 2010-03-16 13:18:55 UTC
Paolo Porelli just mentioned on IRC that there's probably a lot of code out there that implicitly relies on the ordering of tasks by priorities where executing them in a different order would cause SEGVs.
So Philippe's request is definitely a WONTFIX.
Comment 4 Christian Dywan 2010-03-16 13:28:48 UTC
(In reply to comment #2)
> I don't think I agree. And the main loop docs clearly state that this is going
> to happen: "Events from high priority sources are always processed before
> events from lower priority sources."
> The reason is quite simple: If you add some idle task it should be assumed it
> really is an _idle_ task, i.e. something that can be executed whenever there is
> time available and does not need to be executed at all. I'd imagine Gnumeric
> recomputing all cells, VMs running their GC, Abiword relayouting the whole
> document or the treeview recomputing sizes for invisible rows in an idle
> handler and those should not be executed while something important happens
> (like you pasting a lot of text into Gnumeric or Abiword).

I disagree with "does not need to be executed". The documentation makes it clear that high priority tasks will take precedence but that doesn't imply that idles are dropped randomly. A lot of code assumes that g_idle means "run when there is time, defer it if you will, but run it", not "run if you like".
Comment 5 Owen Taylor 2010-03-16 14:52:50 UTC
(In reply to comment #3)
> Paolo Porelli just mentioned on IRC that there's probably a lot of code out
> there that implicitly relies on the ordering of tasks by priorities where
> executing them in a different order would cause SEGVs.
> So Philippe's request is definitely a WONTFIX.

I agree with this - you can debate whether the way that the main loop is set up is right or not, but this sort of change in the scheduling algorithm is going to break things, quite possibly in incredibly subtle ways.
Comment 6 Benjamin Otte (Company) 2010-03-17 12:19:42 UTC
So I guess I'll WONTFIX this. It's intended behavior.