libcpc.c revision c7a079a873b863c236656bd0db7b2cf390841b4d
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A * The library uses the cpc_lock field of the cpc_t struct to protect access to 2N/A * the linked lists inside the cpc_t, and only the linked lists. It is NOT used 2N/A * to protect against a user shooting his/herself in the foot (such as, for 2N/A * instance, destroying the same set at the same time from different threads.). 2N/A * SIGEMT needs to be blocked while holding the lock, to prevent deadlock among 2N/A * an app holding the lock and a signal handler attempting to sample or bind. 2N/A * v1 clients must stick to the v1 interface: cpc_version() 2N/A * Call the syscall with invalid parameters. If we get ENOSYS this CPU 2N/A * has no CPC support. We need to block SIGSYS because the syscall code 2N/A * will send the signal if the system call fails to load. 2N/A for (j = 0; j < i; j++)
2N/A * Ensure state is cleaned up: 2N/A * - Hardware is unbound 2N/A * - Sets are all destroyed 2N/A * - Bufs are all freed * Remove this set from the cpc handle's list of sets. const char *
fn =
"cpc_set_add_request";
for (i = 0; i <
npics; i++)
for (i = 0; i <
nattrs; i++) {
* Verify that each attribute name is legal and valid. * If the user requested a specific picnum, ensure that * the pic can count the requested event. for (i = 0; i <
nattrs; i++) {
* Remove this buf from the cpc handle's list of bufs. * We don't bother checking cpc_set_valid() here, because this is in the * fast path of an app doing SIGEMT-based profiling as they restart the * counters from their signal handler. * cpc_bind_pctx() currently has no valid flags. const char *
fn =
"cpc_bind_cpu";
* cpc_bind_cpu() currently has no valid flags. * To avoid leaking file descriptors, if we find an existing fd here we * just close it. This is only a problem if a user attempts to bind the * same set to different CPUs without first unbinding it. * The following check ensures that only the most recently bound set * can be sampled, as binding a set invalidates all other sets in the * Gets or sets the value of the request specified by index. * Need to reconstruct a temporary cpc_attr_t array for req. /* Skip any generic event names we find. */ if ((
strncmp(p,
"PAPI",
4)) == 0) {
if ((
strncmp(p,
"PAPI",
4)) != 0) {
/* Skip any platform specific event names we find. */ if ((
strncmp(p,
"PAPI",
4)) != 0) {
if ((
strncmp(p,
"PAPI",
4)) == 0) {
* List now points to a comma-separated list of events supported by /* Skip any generic event names we find. */ if ((
strncmp(p,
"PAPI",
4)) == 0) {
* List now points to a comma-separated list of events supported by /* Skip any platform specific event names we find. */ if ((
strncmp(p,
"PAPI",
4)) != 0) {
* Platforms with no attributes will return an empty string. * List now points to a comma-separated list of attributes supported by * the underlying platform. * These strings may contain printf() conversion specifiers. static const char *
errstr[] = {
"",
/* zero slot filler */ "Unknown event\n",
/* CPC_INVALID_EVENT */ "Invalid counter number\n",
/* CPC_INVALID_PICNUM */ "Unknown attribute\n",
/* CPC_INVALID_ATTRIBUTE */ "Attribute out of range\n",
/* CPC_ATTRIBUTE_OUT_OF_RANGE */ "Hardware resource unavailable\n",
/* CPC_RESOURCE_UNAVAIL */ "Counter cannot count requested event\n",
/* CPC_PIC_NOT_CAPABLE */ "Invalid flags in a request\n",
/* CPC_REQ_INVALID_FLAGS */ "Requests conflict with each other\n",
/* CPC_CONFLICTING_REQS */ "Attribute requires the cpc_cpu privilege\n",
/* CPC_ATTR_REQUIRES_PRIVILEGE */ "Couldn't bind LWP to requested processor\n",
/* CPC_PBIND_FAILED */ "Hypervisor event access denied\n" /* CPC_HV_NO_ACCESS */ * If subcode is -1, there is no specific description for this error. * We need to preserve errno across calls to this function to prevent it * from being clobbered while here, or in the user's error handler. * If printf() conversion specifiers are added to the errstr[] * table, this call needs to be changed to vfprintf(). * Hook used by libpctx to alert libcpc when a pctx handle is going away. * This is necessary to prevent libcpc from attempting a libpctx operation on a * stale and invalid pctx_t handle. Since pctx_t's are cached by libcpc, we need * to be notified when they go away. * Check that the set is valid; if so it will be in the cpc handle's * list of sets. The lock protects the list of sets, but not the set * Before assuming this is an invalid event, see if we have been given * a raw event code. An event code of '0' is not recognized, as it * already has a corresponding event name in existing backends and it * is the only reasonable way to know if strtol() succeeded. * Check the second argument of strtol() to ensure invalid events * beginning with number do not go through. * Success - this is a valid raw code in hex, decimal, or octal.