GNOME Bugzilla – Bug 675485
High CPU on idle application, on Windows, signal_timeout
Last modified: 2014-01-31 09:14:50 UTC
Created attachment 213479 [details] Test case Iinkscape recent releases idle (even minimized) at 16-17% cpu on Windows. This problem does not appear on Mac or Linux. (Test system: XP SP3, 32 bit.) https://bugs.launchpad.net/inkscape/+bug/871968 Tracked it down to Glib::signal_timeout(), presumably interacting (badly) with the main loop, possibly g_poll or something like tht. (See the above bug report for details). This problem was previously reported here: http://mail.gnome.org/archives/gtkmm-list/2009-July/msg00127.html The issue can be demonstrated with the tiny program from the above post. I have packaged that up with build scripts and attached it. The test program gives exactly the same amount of idle CPU usage as does inkscape, and the amount changes with the millisecond parameter the same way. For this test I used whatever Mingw was current earlier in the week, and Inkscape devlibs rev29 (also as this is written, the current version.) (The component was a guess.)
These are the versions of everything in devlibs aspell 0.60.5 atk 1.32.0 boost 1.44.0 cairo 1.11.2 cairomm 1.10.0 expat 2.0.0 fontconfig 2.8.0 freetype 2.4.2 gc 6.8 gdk-pixbuf 2.24.0 gettext-tools 0.18.1.1 gettext-runtime 0.18.1.1 glib 2.28.8 glibmm 2.26.0 gtk 2.24.8 gtkmm 2.22.0 ImageMagick 6.5.9 lcms 1.17 libcroco 0.6.1 libgsf 1.14.4 libiconv 1.9.1 libpng 1.2.8 librsvg 2.18.2 libsigc++ 2.2.4.2 libwpg 0.1.0 libxml2 2.7.7 libxslt 1.1.22 openssl 0.9.8g pango 1.28.3 pangomm 2.28.0 pixman 0.22.0 poppler 0.12.1 popt 1.10.4 zlib 1.2.5 perl 5.8.7 python 2.6.5 lxml 2.2.4 numpy 1.4.1 uniconvertor 1.1.5
Ran the test case executable under wine and it used 10% CPU time. Built and tested the test_glib_bug program on an Ubuntu systems as a pure linux version with: g++ -c test_glib_bug.cpp -mms-bitfields -I/include -I/usr/include/gtkmm-2.4 -I/usr/include/glibmm-2.4 -I/usr/lib/glibmm-2.4/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sigc++-2.0/sigc++ -I/usr/include/sigc++-2.0 -I/usr/lib/sigc++-2.0/include -I/usr/include/giomm-2.4 -I/usr/include/gdkmm-2.4 -I/usr/include/gtk-2.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/lib/gtk-2.0/include -I/usr/lib/gdkmm-2.4/include -I/usr/include/cairomm-1.0 -I/usr/include/freetype2/ -I/usr/include/pangomm-1.4/ -I/usr/lib/pangomm-1.4/include -I/usr/include/atk-1.0/ -I/usr/lib/gtkmm-2.4/include/ -I/usr/include/atkmm-1.6/ g++ -o test_glib_bug test_glib_bug.o -mms-bitfields -L/lib -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lpango-1.0 -lcairo -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lglib-2.0 -lgdkmm-2.4 -lcairo -lgtkmm-2.4 -lglibmm-2.4 -lsigc-2.0 ./test_glib_bug and it used <1% CPU. So whatever this bug is, it affects both 32 bit windows and 32 bit Wine. I do not have 64 bit versions of either for testing. (The underlying hardware was the same in both instances, a dual core Athlon X2 machine.)
Have you tried this with glib, without glibmm, to see whether it is a glibmm problem?
I don't see how to do that since the problem maps to the line Glib::signal_timeout().connect(timeout,33); which is part of glibmm. http://developer.gnome.org/glibmm/unstable/classGlib_1_1SignalTimeout.html I did trace it down to what appears to be a problem in g_timeout_prepare in glib/gmain.c. At least making a change there eliminated the problem: https://bugs.launchpad.net/inkscape/+bug/871968/comments/15
Let me clarify "appears to be a problem" a little. By making the change to g_timeout_prepare, rebulding libglib, and putting those dll's where the test application will find them, but not changing glibmm or anything else, it fixes the high CPU usage problem on XP. That doesn't prove that there isn't some interaction with other libraries that causes a glitch somehow that only manifests in this low level glib timing function, but a simpler explanation is that the timer model used by glib on XP has limitations that the original code didn't take into account, which the modified code works around.
(In reply to comment #4) > I don't see how to do that since the problem maps to the line > > Glib::signal_timeout().connect(timeout,33); That connect() function uses g_timeout_source_new(): http://git.gnome.org/browse/glibmm/tree/glib/glibmm/main.cc#n329 though you should probably first check if it happens with g_timeout_add(). I see that you have reassinged this to glib. Good. However, the glib maintainers will really want a C test case.
(In reply to comment #6) > I see that you have reassinged this to glib. Good. Correction: It now depends on the glib bug #675695 .
Closing this as it doesn't seem to be a glibmm bug.