void breadth_dist(const node<P> top_node,v_array<int> &breadths) { if (top_node.num_children == 0) add_height(0,breadths); else { for (int i = 0; i<top_node.num_children ;i++) breadth_dist(top_node.children[i], breadths); add_height(top_node.num_children, breadths); } }
void depth_dist(int top_scale, const node<P> top_node,v_array<int> &depths) { if (top_node.num_children > 0) for (int i = 0; i<top_node.num_children ;i++) { add_height(top_node.scale, depths); depth_dist(top_scale, top_node.children[i], depths); } }
int height_dist(const node<P> top_node,v_array<int> &heights) { if (top_node.num_children == 0) { add_height(0,heights); return 0; } else { int max_v=0; for (int i = 0; i<top_node.num_children ;i++) { int d = height_dist(top_node.children[i], heights); if (d > max_v) max_v = d; } add_height(1 + max_v, heights); return (1 + max_v); } }
/* * Read stg file and allocate memory for the task graph data structure. */ struct stg * new_task_graph_from_file(char *fn, int *malloced) { FILE *fd; int msize; struct stg *tg; int line_number; char line[2048]; int count; int tasks; int procs; int t; struct stg_task* ptask; int tindex; int ptime; int preds; int p; struct stg_pred* ppred; int ctime; assert(fn != NULL); assert(malloced != NULL); printf("reading '%s' .. ", fn); if ((fd = fopen(fn, "r")) == NULL) { printf("can't open '%s'!\n", fn); exit(EX_IOERR); } /* Allocate header structure. */ msize = sizeof(struct stg); if ((tg = malloc(msize)) == NULL) { printf("can't allocate memory!\n"); exit(EX_OSERR); } *malloced += msize; /* Read first (non-comment) line. */ line_number = 0; read_line_from_file(fd, line, sizeof(line), &line_number, 1); /* Parse line for arguments. */ count = sscanf(line, "%d %d", &tasks, &procs); switch (count) { case EOF: case 0: printf("didn't find any number on line %d!\n", line_number); exit(EX_DATAERR); /* NOTREACHED */ case 1: printf("found 'tasks' (%d) but not 'procs' on line %d!\n", tasks, line_number); exit(EX_DATAERR); /* NOTREACHED */ case 2: if (procs <= 0) { printf("'procs' (%d) is negative or zero on line %d!\n", procs, line_number); exit(EX_DATAERR); /* NOTREACHED */ } if (tasks < 0) { printf("'tasks' (%d) is negative on line %d!\n", tasks, line_number); exit(EX_DATAERR); /* NOTREACHED */ } tg->procs = procs; tg->tasks = tasks; break; default: printf("internal error while reading line %d!\n", line_number); exit(EX_SOFTWARE); /* NOTREACHED */ } /* Allocate memory for task information. */ msize = tasks * sizeof(struct stg_task*); if ((tg->task = malloc(msize)) == NULL) { printf("can't allocate memory!\n"); exit(EX_OSERR); } *malloced += msize; /* Read tasks. */ for (t = 0; t < tasks; t++) { /* Allocate. */ msize = sizeof(struct stg_task); if ((ptask = malloc(msize)) == NULL) { printf("can't allocate memory!\n"); exit(EX_OSERR); } *malloced += msize; tg->task[t] = ptask; /* Read task line. */ read_line_from_file(fd, line, sizeof(line), &line_number, 1); /* Parse. */ count = sscanf(line, "%d %d %d", &tindex, &ptime, &preds); switch (count) { case EOF: case 0: printf("didn't find any number on line %d!\n", line_number); exit(EX_DATAERR); /* NOTREACHED */ case 1: printf("found 'tindex' (%d) but not 'ptime' and 'preds' on line %d!\n", tindex, line_number); exit(EX_DATAERR); /* NOTREACHED */ case 2: printf("found 'tindex' (%d) and 'ptime' (%d) but not 'preds' on line %d!\n", tindex, ptime, line_number); exit(EX_DATAERR); /* NOTREACHED */ case 3: /* Number of args is fine. */ if (tindex != t) { printf("read 'tindex' (%d) but expected value %d on line %d!\n", tindex, t, line_number); exit(EX_DATAERR); /* NOTREACHED */ } if (ptime < 0) { printf("'ptime' (%d) is negative on line %d!\n", ptime, line_number); exit(EX_DATAERR); /* NOTREACHED */ } if (preds < 0 || preds >= tasks) { printf("'preds' (%d) is out of bounds on line %d!\n", preds, line_number); exit(EX_DATAERR); /* NOTREACHED */ } ptask->tindex = tindex; ptask->ptime = ptime; ptask->preds = preds; ptask->height = -1; break; default: printf("internal error while reading line %d!\n", line_number); exit(EX_SOFTWARE); /* NOTREACHED */ } /* Allocate memory for predecessor information. */ msize = ptask->preds * sizeof(struct stg_pred*); if ((ptask->pred = malloc(msize)) == NULL) { printf("can't allocate memory!\n"); exit(EX_OSERR); } *malloced += msize; /* Read preds. */ for (p = 0; p < ptask->preds; p++) { /* Allocate. */ msize = sizeof(struct stg_pred); if ((ppred = malloc(msize)) == NULL) { printf("can't allocate memory!\n"); exit(EX_OSERR); } *malloced += msize; ptask->pred[p] = ppred; /* Read preds line. */ read_line_from_file(fd, line, sizeof(line), &line_number, 1); /* Parse. */ count = sscanf(line, "%d %d", &tindex, &ctime); switch (count) { case EOF: case 0: printf("didn't find any number on line %d!\n", line_number); exit(EX_DATAERR); /* NOTREACHED */ case 1: printf("found 'tindex' (%d) but not 'ctime' on line %d!\n", tindex, line_number); exit(EX_DATAERR); /* NOTREACHED */ case 2: if (tindex < 0 || tindex >= tasks) { printf("'tindex' (%d) is out of bounds on line %d!\n", tindex, line_number); exit(EX_DATAERR); /* NOTREACHED */ } if (ctime < 0) { printf("'ctime' (%d) is negative on line %d!\n", ctime, line_number); exit(EX_DATAERR); /* NOTREACHED */ } ppred->tindex = tindex; ppred->ctime = ctime; break; default: printf("internal error while reading line %d!\n", line_number); exit(EX_SOFTWARE); /* NOTREACHED */ } } } /* * We expect the status line to be the first #-comment line behind the * task graph definitions. */ read_line_from_file(fd, line, sizeof(line), &line_number, 0); /* Finish reading. */ fclose(fd); printf("done. (read %d lines)\n", line_number); /* Was there a status line? */ if (line) { printf("old status: [%s]\n", line); /* .. */ } /* Calculate and add topological height. */ add_height(tg); return (tg); }