FreeBSD/sys/dev/hwpmc/hwpmc_mod.c
/*
 * Removes the association between a target process and a PMC.
 */
Removes the association between a target process and a PMC.
Removes the association between a target process and a PMC .
static void
pmc_unlink_target_process(struct pmc *pm, struct pmc_process *pp)
{
	int ri;
	struct proc *p;
	struct pmc_target *ptgt;
	sx_assert(&pmc_sx, SX_XLOCKED);
	KASSERT(pm != NULL && pp != NULL,
	    ("[pmc,%d] Null pm %p or pp %p", __LINE__, pm, pp));
	KASSERT(pp->pp_refcnt >= 1 && pp->pp_refcnt <= (int) md->pmd_npmc,
	    ("[pmc,%d] Illegal ref count %d on process record %p",
		__LINE__, pp->pp_refcnt, (void *) pp));
	ri = PMC_TO_ROWINDEX(pm);
	PMCDBG3(PRC,TUL,1, "unlink-target pmc=%p ri=%d pmc-process=%p",
	    pm, ri, pp);
	KASSERT(pp->pp_pmcs[ri].pp_pmc == pm,
	    ("[pmc,%d] PMC ri %d mismatch pmc %p pp->[ri] %p", __LINE__,
		ri, pm, pp->pp_pmcs[ri].pp_pmc));
	pp->pp_pmcs[ri].pp_pmc = NULL;
	pp->pp_pmcs[ri].pp_pmcval = (pmc_value_t) 0;
	if (pm->pm_owner->po_owner == pp->pp_proc) {
		pp->pp_flags &= ~PMC_PP_ENABLE_MSR_ACCESS;
		pm->pm_flags &= ~PMC_F_ATTACHED_TO_OWNER;
	}
	pp->pp_refcnt--;
	LIST_FOREACH(ptgt, &pm->pm_targets, pt_next)
		if (ptgt->pt_process == pp)
			break;
	KASSERT(ptgt != NULL, ("[pmc,%d] process %p (pp: %p) not found "
		    "in pmc %p", __LINE__, pp->pp_proc, pp, pm));
	LIST_REMOVE(ptgt, pt_next);
	free(ptgt, M_PMC);
	if (LIST_EMPTY(&pm->pm_targets)) {
		p = pm->pm_owner->po_owner;
		PROC_LOCK(p);
		kern_psignal(p, SIGIO);
		PROC_UNLOCK(p);
		PMCDBG2(PRC,SIG,2, "signalling proc=%p signal=%d", p,
		    SIGIO);
	}
}
static void pmc_unlink_target_process ( struct pmc * pm , struct pmc_process * pp ) { int ri ; struct proc * p ; struct pmc_target * ptgt ; sx_assert ( & pmc_sx , SX_XLOCKED ) ; KASSERT ( pm != NULL && pp != NULL , ( " " , __LINE__ , pm , pp ) ) ; KASSERT ( pp -> pp_refcnt >= 1 && pp -> pp_refcnt <= ( int ) md -> pmd_npmc , ( " " , __LINE__ , pp -> pp_refcnt , ( void * ) pp ) ) ; ri = PMC_TO_ROWINDEX ( pm ) ; PMCDBG3 ( PRC , TUL , 1 , " " , pm , ri , pp ) ; KASSERT ( pp -> pp_pmcs [ ri ] . pp_pmc == pm , ( " " , __LINE__ , ri , pm , pp -> pp_pmcs [ ri ] . pp_pmc ) ) ; pp -> pp_pmcs [ ri ] . pp_pmc = NULL ; pp -> pp_pmcs [ ri ] . pp_pmcval = ( pmc_value_t ) 0 ; if ( pm -> pm_owner -> po_owner == pp -> pp_proc ) { pp -> pp_flags &= ~ PMC_PP_ENABLE_MSR_ACCESS ; pm -> pm_flags &= ~ PMC_F_ATTACHED_TO_OWNER ; } pp -> pp_refcnt -- ; LIST_FOREACH ( ptgt , & pm -> pm_targets , pt_next ) if ( ptgt -> pt_process == pp ) break ; KASSERT ( ptgt != NULL , ( " " " " , __LINE__ , pp -> pp_proc , pp , pm ) ) ; LIST_REMOVE ( ptgt , pt_next ) ; free ( ptgt , M_PMC ) ; if ( LIST_EMPTY ( & pm -> pm_targets ) ) { p = pm -> pm_owner -> po_owner ; PROC_LOCK ( p ) ; kern_psignal ( p , SIGIO ) ; PROC_UNLOCK ( p ) ; PMCDBG2 ( PRC , SIG , 2 , " " , p , SIGIO ) ; } }
Removes the association between a target process and a PMC.
Removes the association between a target process and a PMC .
/* Remove owner-specific flags */ /* Remove the target process from the PMC structure */ /* if the PMC now lacks targets, send the owner a SIGIO */