tally(struct rawarc *rawp) { nltype *parentp; nltype *childp; parentp = nllookup( rawp -> raw_frompc ); childp = nllookup( rawp -> raw_selfpc ); if ( parentp == 0 || childp == 0 ) return; if ( kflag && onlist( kfromlist , parentp -> name ) && onlist( ktolist , childp -> name ) ) { return; } childp -> ncall += rawp -> raw_count; # ifdef DEBUG if ( debug & TALLYDEBUG ) { printf( "[tally] arc from %s to %s traversed %d times\n" , parentp -> name , childp -> name , rawp -> raw_count ); } # endif /* DEBUG */ addarc( parentp , childp , rawp -> raw_count ); }
/* * Enable an already declared but disabled device. */ void enabledev(const char *name, const char *at) { struct devbase *ib, *ab; char atbuf[NAMESIZE]; struct attr *attr; struct nvlist *nv; struct devi *i; const char *cp; int atunit; i = ht_lookup(devitab, name); if (i == NULL) { error("invalid device `%s'", name); return; } ib = i->i_base; if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) { error("invalid attachment name `%s'", at); return; } cp = intern(atbuf); ab = ht_lookup(devbasetab, cp); if (ab == NULL) { error("invalid attachment device `%s'", cp); return; } for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) { attr = nv->nv_ptr; if (onlist(attr->a_devs, ib)) goto foundattachment; } error("%s's cannot attach to %s's", ib->d_name, atbuf); return; foundattachment: while (i && i->i_atdev != ab) i = i->i_alias; if (i == NULL) { error("%s at %s not found", name, at); return; } else i->i_disable = 0; /* Enable */ }
/* * in one top to bottom pass over the topologically sorted namelist * propagate: * printflag as the union of parents' printflags * propfraction as the sum of fractional parents' propfractions * and while we're here, sum time for functions. */ static void doflags( void) { long index; nltype *childp; nltype *oldhead; oldhead = 0; for(index = nname-1; index >= 0; index -= 1){ childp = topsortnlp[index]; /* * if we haven't done this function or cycle, * inherit things from parent. * this way, we are linear in the number of arcs * since we do all members of a cycle (and the cycle itself) * as we hit the first member of the cycle. */ if(childp->cyclehead != oldhead){ oldhead = childp->cyclehead; inheritflags(childp); } #ifdef DEBUG if(debug & PROPDEBUG){ printf("[doflags] "); printname(childp); printf(" inherits printflag %d and propfraction %f\n", childp->printflag, childp->propfraction); } #endif if(!childp->printflag){ /* * printflag is off * it gets turned on by * being on -f list, * or there not being any -f list and not being on -e list. */ if(onlist(flist, childp->name) || (!fflag && !onlist(elist, childp->name))){ childp->printflag = TRUE; } } else{ /* * this function has printing parents: * maybe someone wants to shut it up * by putting it on -e list. (but favor -f over -e) */ if((!onlist(flist, childp->name)) && onlist(elist, childp->name)){ childp->printflag = FALSE; } } if(childp->propfraction == 0.0){ /* * no parents to pass time to. * collect time from children if * its on -F list, * or there isn't any -F list and its not on -E list. */ if(onlist(Flist, childp->name) || (!Fflag && !onlist(Elist, childp->name))){ childp->propfraction = 1.0; } } else{ /* * it has parents to pass time to, * but maybe someone wants to shut it up * by puttting it on -E list. (but favor -F over -E) */ if(!onlist(Flist, childp->name) && onlist(Elist, childp->name)){ childp->propfraction = 0.0; } } childp->propself = childp->time * childp->propfraction; printtime += childp->propself; #ifdef DEBUG if(debug & PROPDEBUG){ printf("[doflags] "); printname(childp); printf(" ends up with printflag %d and propfraction %f\n", childp->printflag, childp->propfraction); printf("time %f propself %f printtime %f\n", childp->time, childp->propself, printtime); } #endif } }
/* * Add the named device as attaching to the named attribute (or perhaps * another device instead) plus unit number. */ void adddev(const char *name, const char *at, struct nvlist *loclist, int flags, int disable) { struct devi *i; /* the new instance */ struct attr *attr; /* attribute that allows attach */ struct devbase *ib; /* i->i_base */ struct devbase *ab; /* not NULL => at another dev */ struct nvlist *nv; struct deva *iba; /* devbase attachment used */ const char *cp; int atunit; char atbuf[NAMESIZE]; int hit; ab = NULL; iba = NULL; if (at == NULL) { /* "at root" */ if ((i = getdevi(name)) == NULL) goto bad; /* * Must warn about i_unit > 0 later, after taking care of * the STAR cases (we could do non-star's here but why * bother?). Make sure this device can be at root. */ ib = i->i_base; hit = 0; for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame) if (onlist(iba->d_atlist, NULL)) { hit = 1; break; } if (!hit) { error("%s's cannot attach to the root", ib->d_name); goto bad; } attr = &errattr; /* a convenient "empty" attr */ } else { if (split(at, strlen(at), atbuf, sizeof atbuf, &atunit)) { error("invalid attachment name `%s'", at); /* (void)getdevi(name); -- ??? */ goto bad; } if ((i = getdevi(name)) == NULL) goto bad; ib = i->i_base; cp = intern(atbuf); /* * Devices can attach to two types of things: Attributes, * and other devices (which have the appropriate attributes * to allow attachment). * * (1) If we're attached to an attribute, then we don't need * look at the parent base device to see what attributes * it has, and make sure that we can attach to them. * * (2) If we're attached to a real device (i.e. named in * the config file), we want to remember that so that * at cross-check time, if the device we're attached to * is missing but other devices which also provide the * attribute are present, we don't get a false "OK." * * (3) If the thing we're attached to is an attribute * but is actually named in the config file, we still * have to remember its devbase. */ /* Figure out parent's devbase, to satisfy case (3). */ ab = ht_lookup(devbasetab, cp); /* Find out if it's an attribute. */ attr = ht_lookup(attrtab, cp); /* Make sure we're _really_ attached to the attr. Case (1). */ if (attr != NULL && onlist(attr->a_devs, ib)) goto findattachment; /* * Else a real device, and not just an attribute. Case (2). * * Have to work a bit harder to see whether we have * something like "tg0 at esp0" (where esp is merely * not an attribute) or "tg0 at nonesuch0" (where * nonesuch is not even a device). */ if (ab == NULL) { error("%s at %s: `%s' unknown", name, at, atbuf); goto bad; } /* * See if the named parent carries an attribute * that allows it to supervise device ib. */ for (nv = ab->d_attrs; nv != NULL; nv = nv->nv_next) { attr = nv->nv_ptr; if (onlist(attr->a_devs, ib)) goto findattachment; } error("%s's cannot attach to %s's", ib->d_name, atbuf); goto bad; findattachment: /* find out which attachment it uses */ hit = 0; for (iba = ib->d_ahead; iba != NULL; iba = iba->d_bsame) if (onlist(iba->d_atlist, attr)) { hit = 1; break; } if (!hit) panic("adddev: can't figure out attachment"); } if ((i->i_locs = fixloc(name, attr, loclist)) == NULL) goto bad; i->i_at = at; i->i_atattr = attr; i->i_atdev = ab; i->i_atdeva = iba; i->i_atunit = atunit; i->i_cfflags = flags; i->i_disable = disable; *iba->d_ipp = i; iba->d_ipp = &i->i_asame; selectbase(ib, iba); /* all done, fall into ... */ bad: nvfreel(loclist); return; }
/* * Define some of a device's allowable parent attachments. * There may be a list of (plain) attributes. */ void defdevattach(struct deva *deva, struct devbase *dev, struct nvlist *atlist, struct nvlist *attrs) { struct nvlist *nv; struct attr *a; struct deva *da; if (dev == &errdev) goto bad; if (deva == NULL) deva = getdevattach(dev->d_name); if (deva == &errdeva) goto bad; if (!dev->d_isdef) { error("attaching undefined device `%s'", dev->d_name); goto bad; } if (deva->d_isdef) { error("redefinition of `%s'", deva->d_name); goto bad; } if (dev->d_ispseudo) { error("pseudo-devices can't attach"); goto bad; } deva->d_isdef = 1; if (has_errobj(attrs, &errattr)) goto bad; for (nv = attrs; nv != NULL; nv = nv->nv_next) { a = nv->nv_ptr; if (a == &errattr) continue; /* already complained */ if (a->a_iattr) error("`%s' is not a plain attribute", a->a_name); } /* Committed! Set up fields. */ deva->d_attrs = attrs; deva->d_atlist = atlist; deva->d_devbase = dev; /* * Turn the `at' list into interface attributes (map each * nv_name to an attribute, or to NULL for root), and add * this device to those attributes, so that children can * be listed at this particular device if they are supported * by that attribute. */ for (nv = atlist; nv != NULL; nv = nv->nv_next) { if (nv->nv_name == NULL) nv->nv_ptr = a = NULL; /* at root */ else nv->nv_ptr = a = getattr(nv->nv_name); if (a == &errattr) continue; /* already complained */ /* * Make sure that an attachment spec doesn't * already say how to attach to this attribute. */ for (da = dev->d_ahead; da != NULL; da = da->d_bsame) if (onlist(da->d_atlist, a)) error("attach at `%s' already done by `%s'", a ? a->a_name : "root", da->d_name); if (a == NULL) continue; /* at root; don't add */ if (!a->a_iattr) error("%s cannot be at plain attribute `%s'", dev->d_name, a->a_name); else a->a_devs = addtoattr(a->a_devs, dev); } /* attach to parent */ *dev->d_app = deva; dev->d_app = &deva->d_bsame; return; bad: nvfreel(atlist); nvfreel(attrs); }