uint32_t kpc_get_running(void) { uint64_t pmc_mask = 0; uint32_t cur_state = 0; if (kpc_is_running_fixed()) cur_state |= KPC_CLASS_FIXED_MASK; pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_CONFIGURABLE_MASK); if (kpc_is_running_configurable(pmc_mask)) cur_state |= KPC_CLASS_CONFIGURABLE_MASK; pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_POWER_MASK); if ((pmc_mask != 0) && kpc_is_running_configurable(pmc_mask)) cur_state |= KPC_CLASS_POWER_MASK; return cur_state; }
int kpc_get_period(uint32_t classes, uint64_t *val) { uint32_t count = 0 ; uint64_t pmc_mask = 0ULL; assert(val); lck_mtx_lock(&kpc_config_lock); if (classes & KPC_CLASS_FIXED_MASK) { /* convert reload values to periods */ count = kpc_get_counter_count(KPC_CLASS_FIXED_MASK); for (uint32_t i = 0; i < count; ++i) *val++ = kpc_fixed_max() - FIXED_RELOAD(i); } if (classes & KPC_CLASS_CONFIGURABLE_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_CONFIGURABLE_MASK); /* convert reload values to periods */ count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) *val++ = kpc_configurable_max() - CONFIGURABLE_RELOAD(i); } if (classes & KPC_CLASS_POWER_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_POWER_MASK); /* convert reload values to periods */ count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) *val++ = kpc_configurable_max() - CONFIGURABLE_RELOAD(i); } lck_mtx_unlock(&kpc_config_lock); return 0; }
int kpc_set_actionid(uint32_t classes, uint32_t *val) { uint32_t count = 0; uint64_t pmc_mask = 0ULL; assert(val); /* NOTE: what happens if a pmi occurs while actionids are being * set is undefined. */ lck_mtx_lock(&kpc_config_lock); if (classes & KPC_CLASS_FIXED_MASK) { count = kpc_get_counter_count(KPC_CLASS_FIXED_MASK); memcpy(&FIXED_ACTIONID(0), val, count*sizeof(uint32_t)); val += count; } if (classes & KPC_CLASS_CONFIGURABLE_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_CONFIGURABLE_MASK); count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) CONFIGURABLE_ACTIONID(i) = *val++; } if (classes & KPC_CLASS_POWER_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_POWER_MASK); count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) CONFIGURABLE_ACTIONID(i) = *val++; } lck_mtx_unlock(&kpc_config_lock); return 0; }
int kpc_get_config(uint32_t classes, kpc_config_t *current_config) { uint32_t count = 0; assert(current_config); if (classes & KPC_CLASS_FIXED_MASK) { kpc_get_fixed_config(¤t_config[count]); count += kpc_get_config_count(KPC_CLASS_FIXED_MASK); } if (classes & KPC_CLASS_CONFIGURABLE_MASK) { uint64_t pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_CONFIGURABLE_MASK); kpc_get_configurable_config(¤t_config[count], pmc_mask); count += kpc_get_config_count(KPC_CLASS_CONFIGURABLE_MASK); } if (classes & KPC_CLASS_POWER_MASK) { uint64_t pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_POWER_MASK); kpc_get_configurable_config(¤t_config[count], pmc_mask); count += kpc_get_config_count(KPC_CLASS_POWER_MASK); } if (classes & KPC_CLASS_RAWPMU_MASK) { // Client shouldn't ask for config words that aren't available. // Most likely, they'd misinterpret the returned buffer if we // allowed this. if( kpc_multiple_clients() ) { return EPERM; } kpc_get_rawpmu_config(¤t_config[count]); count += kpc_get_config_count(KPC_CLASS_RAWPMU_MASK); } return 0; }
int kpc_get_actionid(uint32_t classes, uint32_t *val) { uint32_t count = 0; uint64_t pmc_mask = 0ULL; assert(val); lck_mtx_lock(&kpc_config_lock); if (classes & KPC_CLASS_FIXED_MASK) { count = kpc_get_counter_count(KPC_CLASS_FIXED_MASK); memcpy(val, &FIXED_ACTIONID(0), count*sizeof(uint32_t)); val += count; } if (classes & KPC_CLASS_CONFIGURABLE_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_CONFIGURABLE_MASK); count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) *val++ = CONFIGURABLE_ACTIONID(i); } if (classes & KPC_CLASS_POWER_MASK) { pmc_mask = kpc_get_configurable_pmc_mask(KPC_CLASS_POWER_MASK); count = kpc_configurable_count(); for (uint32_t i = 0; i < count; ++i) if ((1ULL << i) & pmc_mask) *val++ = CONFIGURABLE_ACTIONID(i); } lck_mtx_unlock(&kpc_config_lock); return 0; }
uint32_t kpc_get_counter_count(uint32_t classes) { uint32_t count = 0; if (classes & KPC_CLASS_FIXED_MASK) count += kpc_fixed_count(); if (classes & (KPC_CLASS_CONFIGURABLE_MASK | KPC_CLASS_POWER_MASK)) { uint64_t pmc_msk = kpc_get_configurable_pmc_mask(classes); uint32_t pmc_cnt = kpc_popcount(pmc_msk); count += pmc_cnt; } return count; }
uint32_t kpc_get_config_count(uint32_t classes) { uint32_t count = 0; if (classes & KPC_CLASS_FIXED_MASK) count += kpc_fixed_config_count(); if (classes & (KPC_CLASS_CONFIGURABLE_MASK | KPC_CLASS_POWER_MASK)) { uint64_t pmc_mask = kpc_get_configurable_pmc_mask(classes); count += kpc_configurable_config_count(pmc_mask); } if ((classes & KPC_CLASS_RAWPMU_MASK) && !kpc_multiple_clients()) count += kpc_rawpmu_config_count(); return count; }