From 0e9967735869a4e2bbc92d5d0eea0e2136180d49 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Fri, 28 Sep 2012 08:56:36 +0000 Subject: bootstage: Add time accumulation feature Sometimes we want to add up the amount of time spent in a particular activity when it is happening in a number of discrete chunks. Add bootstage_start() to mark the start of an acitivity and bootstage_accum() to accumulate the time since the last start. Calling these function in pairs results in the accumulated time being collected. Signed-off-by: Simon Glass --- common/bootstage.c | 36 +++++++++++++++++++++++++++++++++--- include/bootstage.h | 27 +++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/common/bootstage.c b/common/bootstage.c index 3275499..e7c3fa8 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -90,6 +90,25 @@ ulong bootstage_mark_name(enum bootstage_id id, const char *name) return bootstage_add_record(id, name, flags, timer_get_boot_us()); } +uint32_t bootstage_start(enum bootstage_id id, const char *name) +{ + struct bootstage_record *rec = &record[id]; + + rec->start_us = timer_get_boot_us(); + rec->name = name; + return rec->start_us; +} + +uint32_t bootstage_accum(enum bootstage_id id) +{ + struct bootstage_record *rec = &record[id]; + uint32_t duration; + + duration = (uint32_t)timer_get_boot_us() - rec->start_us; + rec->time_us += duration; + return duration; +} + static void print_time(unsigned long us_time) { char str[15], *s; @@ -108,8 +127,13 @@ static void print_time(unsigned long us_time) static uint32_t print_time_record(enum bootstage_id id, struct bootstage_record *rec, uint32_t prev) { - print_time(rec->time_us); - print_time(rec->time_us - prev); + if (prev == -1U) { + printf("%11s", ""); + print_time(rec->time_us); + } else { + print_time(rec->time_us); + print_time(rec->time_us - prev); + } if (rec->name) printf(" %s\n", rec->name); else if (id >= BOOTSTAGE_ID_USER) @@ -144,13 +168,19 @@ void bootstage_report(void) qsort(record, ARRAY_SIZE(record), sizeof(*rec), h_compare_record); for (id = 0; id < BOOTSTAGE_ID_COUNT; id++, rec++) { - if (rec->time_us != 0) + if (rec->time_us != 0 && !rec->start_us) prev = print_time_record(rec->id, rec, prev); } if (next_id > BOOTSTAGE_ID_COUNT) printf("(Overflowed internal boot id table by %d entries\n" "- please increase CONFIG_BOOTSTAGE_USER_COUNT\n", next_id - BOOTSTAGE_ID_COUNT); + + puts("\nAccumulated time:\n"); + for (id = 0, rec = record; id < BOOTSTAGE_ID_COUNT; id++, rec++) { + if (rec->start_us) + prev = print_time_record(id, rec, -1); + } } ulong __timer_get_boot_us(void) diff --git a/include/bootstage.h b/include/bootstage.h index 64b2ec6..127c94f 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -247,6 +247,33 @@ ulong bootstage_error(enum bootstage_id id); ulong bootstage_mark_name(enum bootstage_id id, const char *name); +/** + * Mark the start of a bootstage activity. The end will be marked later with + * bootstage_accum() and at that point we accumulate the time taken. Calling + * this function turns the given id into a accumulator rather than and + * absolute mark in time. Accumulators record the total amount of time spent + * in an activty during boot. + * + * @param id Bootstage id to record this timestamp against + * @param name Textual name to display for this id in the report (maybe NULL) + * @return start timestamp in microseconds + */ +uint32_t bootstage_start(enum bootstage_id id, const char *name); + +/** + * Mark the end of a bootstage activity + * + * After previously marking the start of an activity with bootstage_start(), + * call this function to mark the end. You can call these functions in pairs + * as many times as you like. + * + * @param id Bootstage id to record this timestamp against + * @return time spent in this iteration of the activity (i.e. the time now + * less the start time recorded in the last bootstage_start() call + * with this id. + */ +uint32_t bootstage_accum(enum bootstage_id id); + /* Print a report about boot time */ void bootstage_report(void); -- cgit v1.1