From: Yong Shen <yong.s...@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.s...@linaro.org>
---
 clocks.c     |  198 +++++++++++++++++++++++++++++++++++----------------------
 clocks.h     |    3 +-
 powerdebug.c |    2 +
 powerdebug.h |    2 +-
 4 files changed, 126 insertions(+), 79 deletions(-)

diff --git a/clocks.c b/clocks.c
index b556644..47881c5 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,93 @@ 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;
+}
+
+void release_all_clk_info_mem(void)
+{
+       if (clk_head)
+               free(clk_head);
+}
+
 void read_clock_info(char *clkpath)
 {
        DIR *dir;
@@ -389,7 +438,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 +451,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 +506,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 +515,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 +523,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 +584,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..a26d16f 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);
 
+       release_all_clk_info_mem();
+
        return ret < 0;
 }
diff --git a/powerdebug.h b/powerdebug.h
index a122b7f..f97e3b9 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);
-- 
1.7.1


_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to