mod_export void scanhashtable(HashTable ht, int sorted, int flags1, int flags2, ScanFunc scanfunc, int scanflags) { struct scanstatus st; if (ht->scantab) { ht->scantab(ht, scanfunc, scanflags); return; } if (sorted) { int i, ct = ht->ct; VARARR(HashNode, hnsorttab, ct); HashNode *htp, hn; for (htp = hnsorttab, i = 0; i < ht->hsize; i++) for (hn = ht->nodes[i]; hn; hn = hn->next) *htp++ = hn; qsort((void *)hnsorttab, ct, sizeof(HashNode), hnamcmp); st.sorted = 1; st.u.s.tab = hnsorttab; st.u.s.ct = ct; ht->scan = &st; for (htp = hnsorttab, i = 0; i < ct; i++, htp++) if (*htp && ((*htp)->flags & flags1) + !flags1 && !((*htp)->flags & flags2)) scanfunc(*htp, scanflags); ht->scan = NULL; } else { int i, hsize = ht->hsize; HashNode *nodes = ht->nodes; st.sorted = 0; ht->scan = &st; for (i = 0; i < hsize; i++) for (st.u.u = nodes[i]; st.u.u; ) { HashNode hn = st.u.u; st.u.u = st.u.u->next; if ((hn->flags & flags1) + !flags1 && !(hn->flags & flags2)) scanfunc(hn, scanflags); } ht->scan = NULL; } }
mod_export int scanmatchtable(HashTable ht, Patprog pprog, int sorted, int flags1, int flags2, ScanFunc scanfunc, int scanflags) { int match = 0; struct scanstatus st; /* * scantab is currently only used by modules to scan * tables where the contents are generated on the fly from * other objects. Note the fact that in this case pprog, * sorted, flags1 and flags2 are ignore. */ if (!pprog && ht->scantab) { ht->scantab(ht, scanfunc, scanflags); return ht->ct; } if (sorted) { int i, ct = ht->ct; VARARR(HashNode, hnsorttab, ct); HashNode *htp, hn; /* * Because the structure might change under our feet, * we can't apply the flags and the pattern before sorting, * tempting though that is. */ for (htp = hnsorttab, i = 0; i < ht->hsize; i++) for (hn = ht->nodes[i]; hn; hn = hn->next) *htp++ = hn; qsort((void *)hnsorttab, ct, sizeof(HashNode), hnamcmp); st.sorted = 1; st.u.s.hashtab = hnsorttab; st.u.s.ct = ct; ht->scan = &st; for (htp = hnsorttab, i = 0; i < ct; i++, htp++) { if ((!flags1 || ((*htp)->flags & flags1)) && !((*htp)->flags & flags2) && (!pprog || pattry(pprog, (*htp)->nam))) { match++; scanfunc(*htp, scanflags); } } ht->scan = NULL; } else { int i, hsize = ht->hsize; HashNode *nodes = ht->nodes; st.sorted = 0; ht->scan = &st; for (i = 0; i < hsize; i++) for (st.u.u = nodes[i]; st.u.u; ) { HashNode hn = st.u.u; st.u.u = st.u.u->next; if ((!flags1 || (hn->flags & flags1)) && !(hn->flags & flags2) && (!pprog || pattry(pprog, hn->nam))) { match++; scanfunc(hn, scanflags); } } ht->scan = NULL; } return match; }
static int bin_zprof(UNUSED(char *nam), UNUSED(char **args), Options ops, UNUSED(int func)) { if (OPT_ISSET(ops,'c')) { freepfuncs(calls); calls = NULL; ncalls = 0; freeparcs(arcs); arcs = NULL; narcs = 0; } else { VARARR(Pfunc, fs, (ncalls + 1)); Pfunc f, *fp; VARARR(Parc, as, (narcs + 1)); Parc a, *ap; long i; double total; for (total = 0.0, f = calls, fp = fs; f; f = f->next, fp++) { *fp = f; total += f->self; } *fp = NULL; for (a = arcs, ap = as; a; a = a->next, ap++) *ap = a; *ap = NULL; qsort(fs, ncalls, sizeof(f), (int (*) _((const void *, const void *))) cmpsfuncs); qsort(as, narcs, sizeof(a), (int (*) _((const void *, const void *))) cmpparcs); printf("num calls time self name\n-----------------------------------------------------------------------------------\n"); for (fp = fs, i = 1; *fp; fp++, i++) { printf("%2ld) %4ld %8.2f %8.2f %6.2f%% %8.2f %8.2f %6.2f%% %s\n", ((*fp)->num = i), (*fp)->calls, (*fp)->time, (*fp)->time / ((double) (*fp)->calls), ((*fp)->time / total) * 100.0, (*fp)->self, (*fp)->self / ((double) (*fp)->calls), ((*fp)->self / total) * 100.0, (*fp)->name); } qsort(fs, ncalls, sizeof(f), (int (*) _((const void *, const void *))) cmptfuncs); for (fp = fs; *fp; fp++) { printf("\n-----------------------------------------------------------------------------------\n\n"); for (ap = as; *ap; ap++) if ((*ap)->to == *fp) { printf(" %4ld/%-4ld %8.2f %8.2f %6.2f%% %8.2f %8.2f %s [%ld]\n", (*ap)->calls, (*fp)->calls, (*ap)->time, (*ap)->time / ((double) (*ap)->calls), ((*ap)->time / total) * 100.0, (*ap)->self, (*ap)->self / ((double) (*ap)->calls), (*ap)->from->name, (*ap)->from->num); } printf("%2ld) %4ld %8.2f %8.2f %6.2f%% %8.2f %8.2f %6.2f%% %s\n", (*fp)->num, (*fp)->calls, (*fp)->time, (*fp)->time / ((double) (*fp)->calls), ((*fp)->time / total) * 100.0, (*fp)->self, (*fp)->self / ((double) (*fp)->calls), ((*fp)->self / total) * 100.0, (*fp)->name); for (ap = as + narcs - 1; ap >= as; ap--) if ((*ap)->from == *fp) { printf(" %4ld/%-4ld %8.2f %8.2f %6.2f%% %8.2f %8.2f %s [%ld]\n", (*ap)->calls, (*ap)->to->calls, (*ap)->time, (*ap)->time / ((double) (*ap)->calls), ((*ap)->time / total) * 100.0, (*ap)->self, (*ap)->self / ((double) (*ap)->calls), (*ap)->to->name, (*ap)->to->num); } } } return 0; }