From: Yong Shen yong.shen@linaro.org
everytime when screen refresh, the clock_info data stucture will be reacclocated, which does not make sence. This patch addresses this issue.
Signed-off-by: Yong Shen yong.shen@linaro.org --- clocks.c | 204 ++++++++++++++++++++++++++++++++++++---------------------- clocks.h | 3 +- powerdebug.c | 2 + powerdebug.h | 3 +- 4 files changed, 133 insertions(+), 79 deletions(-)
diff --git a/clocks.c b/clocks.c index b556644..dc5c03b 100644 --- a/clocks.c +++ b/clocks.c @@ -133,18 +133,18 @@ static void dump_parent(struct clock_info *clk, int line, bool dump) static struct clock_info *find_clock(struct clock_info *clk, char *clkarg) { int i; - struct clock_info *ret = clk; + struct clock_info *ret = clk, *tmp;
if (!strcmp(clk->name, clkarg)) return ret;
if (clk->children) { - for (i = 0; i < clk->num_children; i++) { - if (!strcmp(clk->children[i]->name, clkarg)) - return clk->children[i]; + for (tmp = clk->children, i = 0; i < clk->num_children; i++, tmp = tmp->buddy) { + if (!strcmp(tmp->name, clkarg)) + return tmp; } - for (i = 0; i < clk->num_children; i++) { - ret = find_clock(clk->children[i], clkarg); + for (tmp = clk->children, i = 0; i < clk->num_children; i++, tmp = tmp->buddy) { + ret = find_clock(tmp, clkarg); if (ret) return ret; } @@ -194,51 +194,11 @@ void find_parents_for_clock(char *clkname, int complete) dump_all_parents(clkname, false); }
-static void destroy_clocks_info_recur(struct clock_info *clock) -{ - int i; - - if (clock && clock->num_children) { - for (i = (clock->num_children - 1); i >= 0; i--) { - fflush(stdin); - destroy_clocks_info_recur(clock->children[i]); - if (!i) { - free(clock->children); - clock->children = NULL; - clock->num_children = 0; - } - } - } -} - -static void destroy_clocks_info(void) -{ - int i; - - if (!clocks_info) - return; - - if (clocks_info->num_children) { - for (i = (clocks_info->num_children - 1); i >= 0 ; i--) { - destroy_clocks_info_recur(clocks_info->children[i]); - if (!i) { - free(clocks_info->children); - clocks_info->children = NULL; - } - } - } - clocks_info->num_children = 0; - free(clocks_info); - clocks_info = NULL; -} - - int read_and_print_clock_info(int verbose, int hrow, int selected) { print_one_clock(0, "Reading Clock Tree ...", 1, 1);
if (!old_clock_line_no || selected == REFRESH_WINDOW) { - destroy_clocks_info(); read_clock_info(clk_dir_path); }
@@ -280,11 +240,12 @@ static void prepare_name_str(char *namestr, struct clock_info *clock) static void collapse_all_subclocks(struct clock_info *clock) { int i; + struct clock_info *tmp;
clock->expanded = 0; if (clock->num_children) - for (i = 0; i < clock->num_children; i++) - collapse_all_subclocks(clock->children[i]); + for (tmp = clock->children, i = 0; i < clock->num_children; i++, tmp = tmp->buddy) + collapse_all_subclocks(tmp); }
static void add_clock_details_recur(struct clock_info *clock, @@ -295,6 +256,7 @@ static void add_clock_details_recur(struct clock_info *clock, char rate_str[64]; char name_str[256]; double drate = (double)clock->rate; + struct clock_info *tmp;
if (drate > 1000 && drate < 1000000) { unit = "KHz"; @@ -324,23 +286,23 @@ static void add_clock_details_recur(struct clock_info *clock, }
if (clock->expanded && clock->num_children) - for (i = 0; i < clock->num_children; i++) - add_clock_details_recur(clock->children[i], - hrow, selected); + for (tmp = clock->children, i = 0; i < clock->num_children; i++, tmp = tmp->buddy) + add_clock_details_recur(tmp, hrow, selected); + strcpy(clock_lines[clock_line_no], ""); }
void print_clock_info(int verbose, int hrow, int selected) { int i, count = 0, delta; + struct clock_info *tmp;
(void)verbose;
print_clock_header();
- for (i = 0; i < clocks_info->num_children; i++) - add_clock_details_recur(clocks_info->children[i], - hrow, selected); + for (tmp = clocks_info->children, i = 0; i < clocks_info->num_children; i++, tmp = tmp->buddy) + add_clock_details_recur(tmp, hrow, selected);
delta = calc_delta_screen_size(hrow);
@@ -377,6 +339,99 @@ void read_and_dump_clock_info(int verbose) printf("\n\n"); }
+static struct clock_info *clk_head; +static unsigned int max_node_num, max_clk_num, alloc_index; +static int clk_number_recursive(char *clk_path) +{ + DIR *dir; + struct dirent *item; + char filename[NAME_MAX]; + int ret; + struct stat buf; + + dir = opendir(clk_path); + if (!dir) + return 0; + + while ((item = readdir(dir))) { + /* skip hidden dirs except ".." */ + if (item->d_name[0] == '.') + continue; + + sprintf(filename, "%s/%s", clk_path, item->d_name); + ret = stat(filename, &buf); + + if (ret < 0) { + printf("Error doing a stat on %s\n", filename); + exit(1); + } + + if (!S_ISDIR(buf.st_mode)) + continue; + + max_clk_num++; + clk_number_recursive(filename); + } + closedir(dir); + + return max_clk_num; +} + +static int get_clk_number(char *clk_path) +{ + if ((max_clk_num != 0)) /* no nodes have been added */ + return max_clk_num; + else { + max_clk_num = 0; + /*recaculate the number*/ + return clk_number_recursive(clk_path); + } +} + +int init_clk_info_memory_allocator(char *clk_path) +{ + int clk_number = get_clk_number(clk_path); + + if (max_node_num < clk_number) { + int alloc_number = clk_number * 2; + /* we need more nodes than actual clock number + to host the extra info due to original design scheme */ + if (max_node_num == 0) + clk_head = (struct clock_info *)malloc( + sizeof(struct clock_info) * alloc_number); + else + clk_head = (struct clock_info *)realloc( + clk_head, + sizeof(struct clock_info *) * alloc_number); + + max_node_num = alloc_number; + } + alloc_index = 0; +} + +inline struct clock_info *alloc_clk_info() +{ + alloc_index++; + /* we are pretty sure we have enough nodes, + since we checked every refresh */ + if (alloc_index < max_node_num) + return &clk_head[alloc_index - 1]; + else + return NULL; +} + +static void release_all_clk_info_mem(void) +{ + if (clk_head) + free(clk_head); +} + +void clock_finalize(void) +{ + release_all_clk_info_mem(); +} + + void read_clock_info(char *clkpath) { DIR *dir; @@ -389,7 +444,8 @@ void read_clock_info(char *clkpath) if (!dir) return;
- clocks_info = (struct clock_info *)malloc(sizeof(struct clock_info)); + init_clk_info_memory_allocator(clkpath); + clocks_info = alloc_clk_info(); memset(clocks_info, 0, sizeof(clocks_info)); strcpy(clocks_info->name, "/"); clocks_info->level = 0; @@ -401,14 +457,14 @@ void read_clock_info(char *clkpath)
strcpy(clockname, item->d_name); sprintf(filename, "%s/%s", clkpath, item->d_name); - cur = (struct clock_info *)malloc(sizeof(struct clock_info)); + cur = alloc_clk_info(); memset(cur, 0, sizeof(struct clock_info)); strcpy(cur->name, clockname); cur->parent = clocks_info; cur->num_children = 0; cur->expanded = 0; cur->level = 1; - insert_children(&clocks_info, cur); + insert_children(clocks_info, cur); child = read_clock_info_recur(filename, 2, cur); } closedir(dir); @@ -456,7 +512,7 @@ struct clock_info *read_clock_info_recur(char *clkpath, int level, if (!S_ISDIR(buf.st_mode)) continue;
- cur = (struct clock_info *)malloc(sizeof(struct clock_info)); + cur = alloc_clk_info(); memset(cur, 0, sizeof(cur)); strcpy(cur->name, item->d_name); cur->children = NULL; @@ -465,7 +521,7 @@ struct clock_info *read_clock_info_recur(char *clkpath, int level, cur->expanded = 0; cur->level = level; child = read_clock_info_recur(filename, level + 1, cur); - insert_children(&parent, cur); + insert_children(parent, cur); cur->parent = parent; } closedir(dir); @@ -473,29 +529,22 @@ struct clock_info *read_clock_info_recur(char *clkpath, int level, return cur; }
-void insert_children(struct clock_info **parent, struct clock_info *clk) +void insert_children(struct clock_info *parent, struct clock_info *clk) { - if (!(*parent)->num_children || (*parent)->children == NULL) { - (*parent)->children = (struct clock_info **) - malloc(sizeof(struct clock_info *)*2); - (*parent)->num_children = 0; - } else - (*parent)->children = (struct clock_info **) - realloc((*parent)->children, - sizeof(struct clock_info *) * - ((*parent)->num_children + 2)); - if ((*parent)->num_children > 0) - (*parent)->children[(*parent)->num_children - 1]->last_child - = 0; + if (parent->children == NULL) + clk->buddy = clk; + else + clk->buddy = parent->children; + parent->children = clk; + clk->last_child = 1; - (*parent)->children[(*parent)->num_children] = clk; - (*parent)->children[(*parent)->num_children + 1] = NULL; - (*parent)->num_children++; + parent->num_children++; }
void dump_clock_info(struct clock_info *clk, int level, int bmp) { int i, j; + struct clock_info *tmp;
if (!clk) return; @@ -541,9 +590,10 @@ void dump_clock_info(struct clock_info *clk, int level, int bmp) xbmp = tbmp & xbmp; } else xbmp = bmp; - for (i = 0; i < clk->num_children; i++) { + + for (tmp = clk->children, i = 0; i < clk->num_children; i++, tmp = tmp->buddy) { tbmp = xbmp | (1 << level); - dump_clock_info(clk->children[i], level + 1, tbmp); + dump_clock_info(tmp, level + 1, tbmp); } } } diff --git a/clocks.h b/clocks.h index 9ad9804..5f8e195 100644 --- a/clocks.h +++ b/clocks.h @@ -25,7 +25,8 @@ struct clock_info { int expanded; int level; struct clock_info *parent; - struct clock_info **children; + struct clock_info *children; + struct clock_info *buddy; } *clocks_info;
extern int clock_init(void); diff --git a/powerdebug.c b/powerdebug.c index 4d55f17..8afe588 100644 --- a/powerdebug.c +++ b/powerdebug.c @@ -389,5 +389,7 @@ int main(int argc, char **argv) powerdebug_dump(options, regulators_info, numregulators) : powerdebug_display(options, regulators_info, numregulators);
+ clock_finalize(); + return ret < 0; } diff --git a/powerdebug.h b/powerdebug.h index a122b7f..72c2578 100644 --- a/powerdebug.h +++ b/powerdebug.h @@ -34,7 +34,7 @@ extern void read_clock_info(char *clkpath); extern struct clock_info *read_clock_info_recur(char *clkpath, int level, struct clock_info *parent); extern void dump_clock_info(struct clock_info *clk, int level, int bmp); -extern void insert_children(struct clock_info **parent, struct clock_info *clk); +extern inline void insert_children(struct clock_info *parent, struct clock_info *clk); extern void find_parents_for_clock(char *clkname, int complete); extern int read_and_print_clock_info(int verbose, int hrow, int selected); extern void print_clock_info(int verbose, int hrow, int selected); @@ -54,3 +54,4 @@ extern void create_selectedwindow(int selectedwindow); struct regulator_info; extern void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbose); +extern void clock_finalize(void);