Measure the time a main loop iteration takes

This commit makes awesome measure how long all the event handling takes. That
is, this measure the time between waking up from poll and going to sleep again.
If that time is above 0.1 seconds, we print a warning and increase the limit for
this warning to the last duration to avoid flooding messages.

This should help figuring out cases were people do stupid things in their
config, like synchronously contacting an IMAP server and getting the number of
unread mails.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2014-03-07 10:39:49 +01:00
parent b6bbae084a
commit 9e9366950e
1 changed files with 29 additions and 3 deletions

View File

@ -25,6 +25,7 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <sys/time.h>
#include <xcb/bigreq.h> #include <xcb/bigreq.h>
#include <xcb/randr.h> #include <xcb/randr.h>
@ -57,6 +58,12 @@ awesome_t globalconf;
/** argv used to run awesome */ /** argv used to run awesome */
static char *awesome_argv; static char *awesome_argv;
/** time of last main loop wakeup */
static struct timeval last_wakeup;
/** current limit for the main loop's runtime */
static float main_loop_iteration_limit = 0.1;
/** Call before exiting. /** Call before exiting.
*/ */
void void
@ -217,9 +224,27 @@ static gint
a_glib_poll(GPollFD *ufds, guint nfsd, gint timeout) a_glib_poll(GPollFD *ufds, guint nfsd, gint timeout)
{ {
guint res; guint res;
struct timeval now, length_time;
float length;
/* Do all deferred work now */
awesome_refresh(); awesome_refresh();
/* Check how long this main loop iteration took */
gettimeofday(&now, NULL);
timersub(&now, &last_wakeup, &length_time);
length = length_time.tv_sec + length_time.tv_usec * 1.0f / 1e6;
if (length > main_loop_iteration_limit) {
warn("Last main loop iteration took %.6f seconds! Increasing limit for "
"this warning to that value.", length);
main_loop_iteration_limit = length;
}
/* Actually do the polling, record time of wakeup and check for new xcb events */
res = g_poll(ufds, nfsd, timeout); res = g_poll(ufds, nfsd, timeout);
gettimeofday(&last_wakeup, NULL);
a_xcb_check(); a_xcb_check();
return res; return res;
} }
@ -410,9 +435,6 @@ main(int argc, char **argv)
if (xcb_cursor_context_new(globalconf.connection, globalconf.screen, &globalconf.cursor_ctx) < 0) if (xcb_cursor_context_new(globalconf.connection, globalconf.screen, &globalconf.cursor_ctx) < 0)
fatal("Failed to initialize xcb-cursor"); fatal("Failed to initialize xcb-cursor");
/* Setup the main context */
g_main_context_set_poll_func(g_main_context_default(), &a_glib_poll);
/* initialize dbus */ /* initialize dbus */
a_dbus_init(); a_dbus_init();
@ -517,6 +539,10 @@ main(int argc, char **argv)
xcb_flush(globalconf.connection); xcb_flush(globalconf.connection);
/* Setup the main context */
g_main_context_set_poll_func(g_main_context_default(), &a_glib_poll);
gettimeofday(&last_wakeup, NULL);
/* main event loop */ /* main event loop */
globalconf.loop = g_main_loop_new(NULL, FALSE); globalconf.loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(globalconf.loop); g_main_loop_run(globalconf.loop);