diff --git a/ChangeLog b/ChangeLog index 0ba1c02c..7e050365 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-11-16 Soren Sandmann + + * TODO: updates + + * module/sysprof-module.c (sysprof_poll): Only select readable + when there is at least eight traces available + + * collector.c (collect_traces): New function, old on_read() + + * collector.c (collector_create_profile): Collect traces here as + well. + 2007-11-16 Soren Sandmann * TODO: Updates diff --git a/TODO b/TODO index b93de00c..78ab7217 100644 --- a/TODO +++ b/TODO @@ -23,9 +23,6 @@ Before 1.0.4: Before 1.2: -* If we profile something that is not very CPU bound, sysprof itself - seems to get a disproportionate amount of the samples. Should look into this. - * Is the move-to-front in process_locate_map() really worth it? * Apparently, if you upgrade the kernel, then don't re-run configure, @@ -772,6 +769,11 @@ Later: -=-=-=-=-=-=-=-=-=-=-=-=-=-=- ALREADY DONE: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +* If we profile something that is not very CPU bound, sysprof itself + seems to get a disproportionate amount of the samples. Should look + into this. Fixed by only returning from poll when there is more + than eight traces available. + * regarding crossing system call barriers: Find out about the virtual dso that linux uses to do fast system calls: diff --git a/collector.c b/collector.c index 22d71e85..c598b166 100644 --- a/collector.c +++ b/collector.c @@ -167,14 +167,8 @@ in_dead_period (Collector *collector) } static void -on_read (gpointer data) +collect_traces (Collector *collector) { - Collector *collector = data; - char c; - - /* Make sure poll() doesn't fire immediately again */ - read (collector->fd, &c, 1); - /* After a reset we ignore samples for a short period so that * a reset will actually cause 'samples' to become 0 */ @@ -183,7 +177,7 @@ on_read (gpointer data) collector->current = collector->map_area->head; return; } - + while (collector->current != collector->map_area->head) { const SysprofStackTrace *trace; @@ -213,6 +207,18 @@ on_read (gpointer data) } } +static void +on_read (gpointer data) +{ + Collector *collector = data; + char c; + + /* Make sure poll() doesn't fire immediately again */ + read (collector->fd, &c, 1); + + collect_traces (collector); +} + static gboolean load_module (void) { @@ -479,6 +485,8 @@ collector_create_profile (Collector *collector) { ResolveInfo info; Profile *profile; + + collect_traces (collector); info.resolved_stash = stack_stash_new ((GDestroyNotify)g_free); info.unique_symbols = g_hash_table_new (g_direct_hash, g_direct_equal); diff --git a/module/sysprof-module.c b/module/sysprof-module.c index d2f5ab5a..71e5e95d 100644 --- a/module/sysprof-module.c +++ b/module/sysprof-module.c @@ -235,17 +235,28 @@ sysprof_read(struct file *file, char *buffer, size_t count, loff_t *offset) return 0; } +static int +n_traces_available (SysprofStackTrace *tail) +{ + SysprofStackTrace *head = &(area->traces[area->head]); + + if (head >= tail) + return head - tail; + else + return SYSPROF_N_TRACES - (tail - head); +} + static unsigned int sysprof_poll(struct file *file, poll_table *poll_table) { SysprofStackTrace *tail = file->private_data; - if (&(area->traces[area->head]) != tail) + if (n_traces_available (tail) >= 8) return POLLIN | POLLRDNORM; poll_wait(file, &wait_for_trace, poll_table); - if (&(area->traces[area->head]) != tail) + if (n_traces_available (tail) >= 8) return POLLIN | POLLRDNORM; return 0;