📄 dt_aggregate.c
字号:
case DTRACEAGG_MIN: case DTRACEAGG_MAX: return (dt_aggregate_countcmp(laddr, raddr)); default: assert(0); } return (0);}static intdt_aggregate_keycmp(const void *lhs, const void *rhs){ dt_ahashent_t *lh = *((dt_ahashent_t **)lhs); dt_ahashent_t *rh = *((dt_ahashent_t **)rhs); dtrace_aggdesc_t *lagg = lh->dtahe_data.dtada_desc; dtrace_aggdesc_t *ragg = rh->dtahe_data.dtada_desc; dtrace_recdesc_t *lrec, *rrec; char *ldata, *rdata; int rval, i, j; if ((rval = dt_aggregate_hashcmp(lhs, rhs)) != 0) return (rval); for (i = 1; i < lagg->dtagd_nrecs - 1; i++) { lrec = &lagg->dtagd_rec[i]; rrec = &ragg->dtagd_rec[i]; ldata = lh->dtahe_data.dtada_data + lrec->dtrd_offset; rdata = rh->dtahe_data.dtada_data + rrec->dtrd_offset; if (lrec->dtrd_size < rrec->dtrd_size) return (-1); if (lrec->dtrd_size > rrec->dtrd_size) return (1); for (j = 0; j < lrec->dtrd_size; j++) { char l = ldata[j]; char r = rdata[j]; if (l < r) return (-1); if (l > r) return (1); } } return (0);}static intdt_aggregate_keyvarcmp(const void *lhs, const void *rhs){ int rval; if ((rval = dt_aggregate_keycmp(lhs, rhs)) != 0) return (rval); return (dt_aggregate_varcmp(lhs, rhs));}static intdt_aggregate_varkeycmp(const void *lhs, const void *rhs){ int rval; if ((rval = dt_aggregate_varcmp(lhs, rhs)) != 0) return (rval); return (dt_aggregate_keycmp(lhs, rhs));}static intdt_aggregate_valvarcmp(const void *lhs, const void *rhs){ int rval; if ((rval = dt_aggregate_valcmp(lhs, rhs)) != 0) return (rval); return (dt_aggregate_varcmp(lhs, rhs));}static intdt_aggregate_varvalcmp(const void *lhs, const void *rhs){ int rval; if ((rval = dt_aggregate_varcmp(lhs, rhs)) != 0) return (rval); return (dt_aggregate_valcmp(lhs, rhs));}static intdt_aggregate_keyvarrevcmp(const void *lhs, const void *rhs){ return (dt_aggregate_keyvarcmp(rhs, lhs));}static intdt_aggregate_varkeyrevcmp(const void *lhs, const void *rhs){ return (dt_aggregate_varkeycmp(rhs, lhs));}static intdt_aggregate_valvarrevcmp(const void *lhs, const void *rhs){ return (dt_aggregate_valvarcmp(rhs, lhs));}static intdt_aggregate_varvalrevcmp(const void *lhs, const void *rhs){ return (dt_aggregate_varvalcmp(rhs, lhs));}intdt_aggregate_go(dtrace_hdl_t *dtp){ dt_aggregate_t *agp = &dtp->dt_aggregate; dtrace_optval_t size, cpu; dtrace_bufdesc_t *buf = &agp->dtat_buf; int rval, i; assert(agp->dtat_maxcpu == 0); assert(agp->dtat_ncpu == 0); assert(agp->dtat_cpus == NULL); agp->dtat_maxcpu = dt_sysconf(dtp, _SC_CPUID_MAX) + 1; agp->dtat_ncpu = dt_sysconf(dtp, _SC_NPROCESSORS_MAX); agp->dtat_cpus = malloc(agp->dtat_ncpu * sizeof (processorid_t)); if (agp->dtat_cpus == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); /* * Use the aggregation buffer size as reloaded from the kernel. */ size = dtp->dt_options[DTRACEOPT_AGGSIZE]; rval = dtrace_getopt(dtp, "aggsize", &size); assert(rval == 0); if (size == 0 || size == DTRACEOPT_UNSET) return (0); buf = &agp->dtat_buf; buf->dtbd_size = size; if ((buf->dtbd_data = malloc(buf->dtbd_size)) == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); /* * Now query for the CPUs enabled. */ rval = dtrace_getopt(dtp, "cpu", &cpu); assert(rval == 0 && cpu != DTRACEOPT_UNSET); if (cpu != DTRACE_CPUALL) { assert(cpu < agp->dtat_ncpu); agp->dtat_cpus[agp->dtat_ncpus++] = (processorid_t)cpu; return (0); } agp->dtat_ncpus = 0; for (i = 0; i < agp->dtat_maxcpu; i++) { if (dt_status(dtp, i) == -1) continue; agp->dtat_cpus[agp->dtat_ncpus++] = i; } return (0);}static intdt_aggwalk_rval(dtrace_hdl_t *dtp, dt_ahashent_t *h, int rval){ dt_aggregate_t *agp = &dtp->dt_aggregate; dtrace_aggdata_t *data; dtrace_aggdesc_t *aggdesc; dtrace_recdesc_t *rec; int i; switch (rval) { case DTRACE_AGGWALK_NEXT: break; case DTRACE_AGGWALK_CLEAR: { uint32_t size, offs = 0; aggdesc = h->dtahe_data.dtada_desc; rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1]; size = rec->dtrd_size; data = &h->dtahe_data; if (rec->dtrd_action == DTRACEAGG_LQUANTIZE) { offs = sizeof (uint64_t); size -= sizeof (uint64_t); } bzero(&data->dtada_data[rec->dtrd_offset] + offs, size); if (data->dtada_percpu == NULL) break; for (i = 0; i < dtp->dt_aggregate.dtat_maxcpu; i++) bzero(data->dtada_percpu[i] + offs, size); break; } case DTRACE_AGGWALK_ERROR: /* * We assume that errno is already set in this case. */ return (dt_set_errno(dtp, errno)); case DTRACE_AGGWALK_ABORT: return (dt_set_errno(dtp, EDT_DIRABORT)); case DTRACE_AGGWALK_DENORMALIZE: h->dtahe_data.dtada_normal = 1; return (0); case DTRACE_AGGWALK_NORMALIZE: if (h->dtahe_data.dtada_normal == 0) { h->dtahe_data.dtada_normal = 1; return (dt_set_errno(dtp, EDT_BADRVAL)); } return (0); case DTRACE_AGGWALK_REMOVE: { dtrace_aggdata_t *aggdata = &h->dtahe_data; int i, max_cpus = agp->dtat_maxcpu; /* * First, remove this hash entry from its hash chain. */ if (h->dtahe_prev != NULL) { h->dtahe_prev->dtahe_next = h->dtahe_next; } else { dt_ahash_t *hash = &agp->dtat_hash; size_t ndx = h->dtahe_hashval % hash->dtah_size; assert(hash->dtah_hash[ndx] == h); hash->dtah_hash[ndx] = h->dtahe_next; } if (h->dtahe_next != NULL) h->dtahe_next->dtahe_prev = h->dtahe_prev; /* * Now remove it from the list of all hash entries. */ if (h->dtahe_prevall != NULL) { h->dtahe_prevall->dtahe_nextall = h->dtahe_nextall; } else { dt_ahash_t *hash = &agp->dtat_hash; assert(hash->dtah_all == h); hash->dtah_all = h->dtahe_nextall; } if (h->dtahe_nextall != NULL) h->dtahe_nextall->dtahe_prevall = h->dtahe_prevall; /* * We're unlinked. We can safely destroy the data. */ if (aggdata->dtada_percpu != NULL) { for (i = 0; i < max_cpus; i++) free(aggdata->dtada_percpu[i]); free(aggdata->dtada_percpu); } free(aggdata->dtada_data); free(h); return (0); } default: return (dt_set_errno(dtp, EDT_BADRVAL)); } return (0);}intdtrace_aggregate_walk(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ dt_ahashent_t *h, *next; dt_ahash_t *hash = &dtp->dt_aggregate.dtat_hash; for (h = hash->dtah_all; h != NULL; h = next) { /* * dt_aggwalk_rval() can potentially remove the current hash * entry; we need to load the next hash entry before calling * into it. */ next = h->dtahe_nextall; if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1) return (-1); } return (0);}static intdt_aggregate_walk_sorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg, int (*sfunc)(const void *, const void *)){ dt_aggregate_t *agp = &dtp->dt_aggregate; dt_ahashent_t *h, **sorted; dt_ahash_t *hash = &agp->dtat_hash; size_t i, nentries = 0; for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) nentries++; sorted = malloc(nentries * sizeof (dt_ahashent_t *)); if (sorted == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); for (h = hash->dtah_all, i = 0; h != NULL; h = h->dtahe_nextall) sorted[i++] = h; qsort(sorted, nentries, sizeof (dt_ahashent_t *), sfunc); for (i = 0; i < nentries; i++) { h = sorted[i]; if (dt_aggwalk_rval(dtp, h, func(&h->dtahe_data, arg)) == -1) return (-1); } free(sorted); return (0);}intdtrace_aggregate_walk_keysorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_varkeycmp));}intdtrace_aggregate_walk_valsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_varvalcmp));}intdtrace_aggregate_walk_keyvarsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_keyvarcmp));}intdtrace_aggregate_walk_valvarsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_valvarcmp));}intdtrace_aggregate_walk_keyrevsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_varkeyrevcmp));}intdtrace_aggregate_walk_valrevsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_varvalrevcmp));}intdtrace_aggregate_walk_keyvarrevsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_keyvarrevcmp));}intdtrace_aggregate_walk_valvarrevsorted(dtrace_hdl_t *dtp, dtrace_aggregate_f *func, void *arg){ return (dt_aggregate_walk_sorted(dtp, func, arg, dt_aggregate_valvarrevcmp));}intdtrace_aggregate_print(dtrace_hdl_t *dtp, FILE *fp, dtrace_aggregate_walk_f *func){ dt_print_aggdata_t pd; pd.dtpa_dtp = dtp; pd.dtpa_fp = fp; pd.dtpa_allunprint = 1; if (func == NULL) func = dtrace_aggregate_walk_valsorted; if ((*func)(dtp, dt_print_agg, &pd) == -1) return (dt_set_errno(dtp, dtp->dt_errno)); return (0);}voiddtrace_aggregate_clear(dtrace_hdl_t *dtp){ dt_aggregate_t *agp = &dtp->dt_aggregate; dt_ahash_t *hash = &agp->dtat_hash; dt_ahashent_t *h; dtrace_aggdata_t *data; dtrace_aggdesc_t *aggdesc; dtrace_recdesc_t *rec; int i, max_cpus = agp->dtat_maxcpu; for (h = hash->dtah_all; h != NULL; h = h->dtahe_nextall) { aggdesc = h->dtahe_data.dtada_desc; rec = &aggdesc->dtagd_rec[aggdesc->dtagd_nrecs - 1]; data = &h->dtahe_data; bzero(&data->dtada_data[rec->dtrd_offset], rec->dtrd_size); if (data->dtada_percpu == NULL) continue; for (i = 0; i < max_cpus; i++) bzero(data->dtada_percpu[i], rec->dtrd_size); }}voiddt_aggregate_destroy(dtrace_hdl_t *dtp){ dt_aggregate_t *agp = &dtp->dt_aggregate; dt_ahash_t *hash = &agp->dtat_hash; dt_ahashent_t *h, *next; dtrace_aggdata_t *aggdata; int i, max_cpus = agp->dtat_maxcpu; if (hash->dtah_hash == NULL) { assert(hash->dtah_all == NULL); } else { free(hash->dtah_hash); for (h = hash->dtah_all; h != NULL; h = next) { next = h->dtahe_nextall; aggdata = &h->dtahe_data; if (aggdata->dtada_percpu != NULL) { for (i = 0; i < max_cpus; i++) free(aggdata->dtada_percpu[i]); free(aggdata->dtada_percpu); } free(aggdata->dtada_data); free(h); } hash->dtah_hash = NULL; hash->dtah_all = NULL; hash->dtah_size = 0; } free(agp->dtat_buf.dtbd_data); free(agp->dtat_cpus);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -