dt_program.c
来自「Sun Solaris 10 中的 DTrace 组件的源代码。请参看: htt」· C语言 代码 · 共 336 行
C
336 行
/* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only. * See the file usr/src/LICENSING.NOTICE in this distribution or * http://www.opensolaris.org/license/ for details. */#pragma ident "@(#)dt_program.c 1.5 04/11/13 SMI"#include <unistd.h>#include <strings.h>#include <stdlib.h>#include <errno.h>#include <assert.h>#include <dt_impl.h>#include <dt_printf.h>dtrace_prog_t *dtrace_program_create(dtrace_hdl_t *dtp){ dtrace_prog_t *pgp = calloc(1, sizeof (dtrace_prog_t)); if (pgp != NULL) dt_list_append(&dtp->dt_programs, pgp); else (void) dt_set_errno(dtp, EDT_NOMEM); return (pgp);}voiddtrace_program_destroy(dtrace_hdl_t *dtp, dtrace_prog_t *pgp){ dt_stmt_t *stp, *next; for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { next = dt_list_next(stp); dtrace_stmt_destroy(stp->ds_desc); free(stp); } dt_list_delete(&dtp->dt_programs, pgp); free(pgp);}/*ARGSUSED*/voiddtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_proginfo_t *pip){ dt_stmt_t *stp; dtrace_actdesc_t *ap; dtrace_ecbdesc_t *last = NULL; if (pip == NULL) return; bzero(pip, sizeof (dtrace_proginfo_t)); if (dt_list_next(&pgp->dp_stmts) != NULL) { pip->dpi_descattr = _dtrace_maxattr; pip->dpi_stmtattr = _dtrace_maxattr; } else { pip->dpi_descattr = _dtrace_defattr; pip->dpi_stmtattr = _dtrace_defattr; } for (stp = dt_list_next(&pgp->dp_stmts); stp; stp = dt_list_next(stp)) { dtrace_ecbdesc_t *edp = stp->ds_desc->dtsd_ecbdesc; if (edp == last) continue; last = edp; pip->dpi_descattr = dt_attr_min(stp->ds_desc->dtsd_descattr, pip->dpi_descattr); pip->dpi_stmtattr = dt_attr_min(stp->ds_desc->dtsd_stmtattr, pip->dpi_stmtattr); /* * If there aren't any actions, account for the fact that * recording the epid will generate a record. */ if (edp->dted_action == NULL) pip->dpi_recgens++; for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { if (ap->dtad_kind == DTRACEACT_SPECULATE) { pip->dpi_speculations++; continue; } if (DTRACEACT_ISAGG(ap->dtad_kind)) { pip->dpi_recgens -= ap->dtad_arg; pip->dpi_aggregates++; continue; } if (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind)) continue; if (ap->dtad_kind == DTRACEACT_DIFEXPR && ap->dtad_difo->dtdo_rtype.dtdt_kind == DIF_TYPE_CTF && ap->dtad_difo->dtdo_rtype.dtdt_size == 0) continue; pip->dpi_recgens++; } }}intdtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_proginfo_t *pip){ void *dof; int n, err; dtrace_program_info(dtp, pgp, pip); if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL) return (-1); n = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof); dtrace_dof_destroy(dof); if (n == -1) { switch (errno) { case EINVAL: err = EDT_DIFINVAL; break; case EFAULT: err = EDT_DIFFAULT; break; case E2BIG: err = EDT_DIFSIZE; break; default: err = errno; } return (dt_set_errno(dtp, err)); } if (pip != NULL) pip->dpi_matches += n; return (0);}voiddtrace_ecbdesc_hold(dtrace_ecbdesc_t *edp){ edp->dted_refcnt++;}voiddtrace_ecbdesc_release(dtrace_ecbdesc_t *edp){ dtrace_difo_t *dp; if (--edp->dted_refcnt > 0) return; if ((dp = edp->dted_pred.dtpdd_difo) != NULL) dtrace_difo_release(dp); assert(edp->dted_action == NULL); free(edp);}dtrace_ecbdesc_t *dtrace_ecbdesc_create(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp){ dtrace_ecbdesc_t *edp; if ((edp = malloc(sizeof (dtrace_ecbdesc_t))) == NULL) { (void) dt_set_errno(dtp, EDT_NOMEM); return (NULL); } bzero(edp, sizeof (dtrace_ecbdesc_t)); edp->dted_probe = *pdp; dtrace_ecbdesc_hold(edp); return (edp);}dtrace_stmtdesc_t *dtrace_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp){ dtrace_stmtdesc_t *sdp; if ((sdp = malloc(sizeof (dtrace_stmtdesc_t))) == NULL) { (void) dt_set_errno(dtp, EDT_NOMEM); return (NULL); } bzero(sdp, sizeof (dtrace_stmtdesc_t)); dtrace_ecbdesc_hold(edp); sdp->dtsd_ecbdesc = edp; sdp->dtsd_descattr = _dtrace_defattr; sdp->dtsd_stmtattr = _dtrace_defattr; return (sdp);}dtrace_actdesc_t *dtrace_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp){ dtrace_actdesc_t *new; dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; if ((new = malloc(sizeof (dtrace_actdesc_t))) == NULL) { (void) dt_set_errno(dtp, EDT_NOMEM); return (NULL); } if (sdp->dtsd_action_last != NULL) { assert(sdp->dtsd_action != NULL); assert(sdp->dtsd_action_last->dtad_next == NULL); sdp->dtsd_action_last->dtad_next = new; } else { dtrace_actdesc_t *ap = edp->dted_action; assert(sdp->dtsd_action == NULL); sdp->dtsd_action = new; while (ap != NULL && ap->dtad_next != NULL) ap = ap->dtad_next; if (ap == NULL) edp->dted_action = new; else ap->dtad_next = new; } sdp->dtsd_action_last = new; bzero(new, sizeof (dtrace_actdesc_t)); new->dtad_uarg = (uintptr_t)sdp; return (new);}intdtrace_stmt_add(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp){ dt_stmt_t *stp = malloc(sizeof (dt_stmt_t)); if (stp == NULL) return (dt_set_errno(dtp, EDT_NOMEM)); dt_list_append(&pgp->dp_stmts, stp); stp->ds_desc = sdp; return (0);}intdtrace_stmt_iter(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmt_f *func, void *data){ dt_stmt_t *stp, *next; int status = 0; for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) { next = dt_list_next(stp); if ((status = func(dtp, pgp, stp->ds_desc, data)) != 0) break; } return (status);}voiddtrace_stmt_destroy(dtrace_stmtdesc_t *sdp){ dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc; /* * We need to remove any actions that we have on this ECB, and * remove our hold on the ECB itself. */ if (sdp->dtsd_action != NULL) { dtrace_actdesc_t *last = sdp->dtsd_action_last; dtrace_actdesc_t *ap, *next; assert(last != NULL); for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) { if (ap == sdp->dtsd_action) break; if (ap->dtad_next == sdp->dtsd_action) break; } assert(ap != NULL); if (ap == edp->dted_action) { edp->dted_action = last->dtad_next; } else { ap->dtad_next = last->dtad_next; } /* * We have now removed our action list from its ECB; we can * safely destroy the list. */ last->dtad_next = NULL; for (ap = sdp->dtsd_action; ap != NULL; ap = next) { dtrace_difo_t *dp; assert(ap->dtad_uarg == (uintptr_t)sdp); if ((dp = ap->dtad_difo) != NULL) dtrace_difo_release(dp); next = ap->dtad_next; free(ap); } } if (sdp->dtsd_fmtdata != NULL) dt_printf_destroy(sdp->dtsd_fmtdata); dtrace_ecbdesc_release(sdp->dtsd_ecbdesc); free(sdp);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?