Add a generic way to call per event allocate / release function.

Reviewed by:	mav
MFC after:	1 month
This commit is contained in:
Fabien Thomas 2013-03-05 10:18:48 +00:00
parent e6cd8542ed
commit d49302aead
3 changed files with 24 additions and 9 deletions

View File

@ -45,8 +45,6 @@ __FBSDID("$FreeBSD$");
#define SOFT_CAPS (PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INTERRUPT | \
PMC_CAP_USER | PMC_CAP_SYSTEM)
PMC_SOFT_DECLARE( , , clock, prof);
struct soft_descr {
struct pmc_descr pm_descr; /* "base class" */
};
@ -126,9 +124,10 @@ soft_allocate_pmc(int cpu, int ri, struct pmc *pm,
if (ps == NULL)
return (EINVAL);
pmc_soft_ev_release(ps);
/* Module unload is protected by pmc SX lock. */
if (ps->ps_alloc != NULL)
ps->ps_alloc();
if (ev == pmc___clock_prof.ps_ev.pm_ev_code)
cpu_startprofclock();
return (0);
}
@ -315,6 +314,8 @@ static int
soft_release_pmc(int cpu, int ri, struct pmc *pmc)
{
struct pmc_hw *phw;
enum pmc_event ev;
struct pmc_soft *ps;
(void) pmc;
@ -328,8 +329,16 @@ soft_release_pmc(int cpu, int ri, struct pmc *pmc)
KASSERT(phw->phw_pmc == NULL,
("[soft,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
if (pmc->pm_event == pmc___clock_prof.ps_ev.pm_ev_code)
cpu_stopprofclock();
ev = pmc->pm_event;
/* Check if event is registered. */
ps = pmc_soft_ev_acquire(ev);
KASSERT(ps != NULL,
("[soft,%d] unregistered event %d", __LINE__, ev));
pmc_soft_ev_release(ps);
/* Module unload is protected by pmc SX lock. */
if (ps->ps_release != NULL)
ps->ps_release();
return (0);
}

View File

@ -78,7 +78,8 @@ __FBSDID("$FreeBSD$");
#include <sys/pmckern.h>
PMC_SOFT_DEFINE( , , clock, hard);
PMC_SOFT_DEFINE( , , clock, stat);
PMC_SOFT_DEFINE( , , clock, prof);
PMC_SOFT_DEFINE_EX( , , clock, prof, \
cpu_startprofclock, cpu_stopprofclock);
#endif
#ifdef DEVICE_POLLING

View File

@ -87,9 +87,9 @@ struct pmckern_soft {
* Soft PMC.
*/
#define PMC_SOFT_DEFINE(prov, mod, func, name) \
#define PMC_SOFT_DEFINE_EX(prov, mod, func, name, alloc, release) \
struct pmc_soft pmc_##prov##_##mod##_##func##_##name = \
{ 0, { #prov "_" #mod "_" #func "." #name, 0 } }; \
{ 0, alloc, release, { #prov "_" #mod "_" #func "." #name, 0 } }; \
SYSINIT(pmc_##prov##_##mod##_##func##_##name##_init, SI_SUB_KDTRACE, \
SI_ORDER_SECOND + 1, pmc_soft_ev_register, \
&pmc_##prov##_##mod##_##func##_##name ); \
@ -97,6 +97,9 @@ struct pmckern_soft {
SI_SUB_KDTRACE, SI_ORDER_SECOND + 1, pmc_soft_ev_deregister, \
&pmc_##prov##_##mod##_##func##_##name )
#define PMC_SOFT_DEFINE(prov, mod, func, name) \
PMC_SOFT_DEFINE_EX(prov, mod, func, name, NULL, NULL)
#define PMC_SOFT_DECLARE(prov, mod, func, name) \
extern struct pmc_soft pmc_##prov##_##mod##_##func##_##name
@ -147,6 +150,8 @@ do { \
struct pmc_soft {
int ps_running;
void (*ps_alloc)(void);
void (*ps_release)(void);
struct pmc_dyn_event_descr ps_ev;
};