FreeBSD/usr.sbin/pmcstat/pmcpl_callgraph.c
/*
 * Printing a callgraph for a PMC.
 */
Printing a callgraph for a PMC.
Printing a callgraph for a PMC .
static void
pmcstat_callgraph_print_for_pmcid(struct pmcstat_pmcrecord *pmcr)
{
	int n, nentries;
	uint32_t nsamples;
	pmc_id_t pmcid;
	struct pmcstat_cgnode **sortbuffer, **cgn;
	struct pmcstat_cgnode_hash *pch;
	nsamples = 0;
	pmcid = pmcr->pr_pmcid;
	if ((sortbuffer = (struct pmcstat_cgnode **)
	    malloc(sizeof(struct pmcstat_cgnode *) *
	    pmcstat_cgnode_hash_count)) == NULL)
		err(EX_OSERR, "ERROR: Cannot sort callgraph");
	cgn = sortbuffer;
	for (n = 0; n < PMCSTAT_NHASH; n++)
		LIST_FOREACH(pch, &pmcstat_cgnode_hash[n], pch_next)
		    if (pch->pch_pmcid == pmcid) {
			    nsamples += pch->pch_cgnode->pcg_count;
			    *cgn++ = pch->pch_cgnode;
		    }
	nentries = cgn - sortbuffer;
	assert(nentries <= pmcstat_cgnode_hash_count);
	if (nentries == 0) {
		free(sortbuffer);
		return;
	}
	qsort(sortbuffer, nentries, sizeof(struct pmcstat_cgnode *),
	    pmcstat_cgnode_compare);
	(void) fprintf(args.pa_graphfile,
	    "@ %s [%u samples]\n\n",
	    pmcstat_string_unintern(pmcr->pr_pmcname),
	    nsamples);
	for (cgn = sortbuffer, n = 0; n < nentries; n++, cgn++) {
		pmcstat_previous_filename_printed = NULL;
		pmcstat_cgnode_print(*cgn, 0, nsamples);
		(void) fprintf(args.pa_graphfile, "\n");
	}
	free(sortbuffer);
}
static void pmcstat_callgraph_print_for_pmcid ( struct pmcstat_pmcrecord * pmcr ) { int n , nentries ; uint32_t nsamples ; pmc_id_t pmcid ; struct pmcstat_cgnode * * sortbuffer , * * cgn ; struct pmcstat_cgnode_hash * pch ; nsamples = 0 ; pmcid = pmcr -> pr_pmcid ; if ( ( sortbuffer = ( struct pmcstat_cgnode * * ) malloc ( sizeof ( struct pmcstat_cgnode * ) * pmcstat_cgnode_hash_count ) ) == NULL ) err ( EX_OSERR , " " ) ; cgn = sortbuffer ; for ( n = 0 ; n < PMCSTAT_NHASH ; n ++ ) LIST_FOREACH ( pch , & pmcstat_cgnode_hash [ n ] , pch_next ) if ( pch -> pch_pmcid == pmcid ) { nsamples += pch -> pch_cgnode -> pcg_count ; * cgn ++ = pch -> pch_cgnode ; } nentries = cgn - sortbuffer ; assert ( nentries <= pmcstat_cgnode_hash_count ) ; if ( nentries == 0 ) { free ( sortbuffer ) ; return ; } qsort ( sortbuffer , nentries , sizeof ( struct pmcstat_cgnode * ) , pmcstat_cgnode_compare ) ; ( void ) fprintf ( args . pa_graphfile , " \n \n " , pmcstat_string_unintern ( pmcr -> pr_pmcname ) , nsamples ) ; for ( cgn = sortbuffer , n = 0 ; n < nentries ; n ++ , cgn ++ ) { pmcstat_previous_filename_printed = NULL ; pmcstat_cgnode_print ( * cgn , 0 , nsamples ) ; ( void ) fprintf ( args . pa_graphfile , " \n " ) ; } free ( sortbuffer ) ; }
Printing a callgraph for a PMC.
Printing a callgraph for a PMC .
/*
	 * We pull out all callgraph nodes in the top-level hash table
	 * with a matching PMC id.  We then sort these based on the
	 * frequency of occurrence.  Each callgraph node is then
	 * printed.
	 */