Sugar apps' pygtk main loop polls 10 times a second, always
|Reported by:||gnu||Owned by:||marco|
|Keywords:||power, performance||Cc:||jg, krstic, tomeu, cjb, bemasc, cscott, dsd|
|Deployments affected:||Action Needed:||never set|
The interface between Python and GTK+ limits the GTK+ main loop's ability to sleep when idle, forcing it to wake up every 100 ms.
This appears to be true for every Python program that calls GTK+.
I noticed that the SimCity Python helper process was doing tons of system calls -- lots of poll() calls with timeouts of 100ms. You can see this by running the strace command on any Python sugar application, such as the Journal's sugar-activity-factory,
So I debugged the SimCity one. The timeout is used in the poll() call in g_main_loop_run() in glib2, and is set by this code in pygtk_main_watch_prepare in pygtk2's gtk.override:
1058 /* This code (pygtk main watch) was copied with minor changes from
1059 * pygobject/gobject/pygmainloop.c */
1060 static gboolean
1061 pygtk_main_watch_prepare(GSource *source,
1062 int *timeout)
1064 /* Python only invokes signal handlers from the main thread,
1065 * so if a thread other than the main thread receives the signal
1066 * from the kernel, !PyErr_CheckSignals() from that thread will
1067 * do nothing. So, we need to time out and check for signals
1068 * regularily too.
1069 * Also, on Windows g_poll() won't be interrupted by a signal
1070 * (AFAIK), so we need the timeout there too.
1072 #ifndef PLATFORM_WIN32
1073 if (pyg_threads_enabled)
1075 *timeout = 100;
Clearly, this code should not be waking up every 10th of a second to "check for signals regularily" -- neither on the OLPC, nor on other machines running Python GTK applications. But I don't know enough about this code to suggest a fix.
Bug #4677 is a tracker for similar bugs.