pfm_get_os_event_encoding - get event encoding for a specific
operating system
#include <perfmon/pfmlib.h>
int pfm_get_os_event_encoding(const char *str, int dfl_plm, pfm_os_t os, void *arg);
This is the key function to retrieve the encoding of an event for
a specific operating system interface. The event string passed in str
is parsed and encoded for the operating system specified by os. Only
one event per call can be encoded. As such, str can contain only one
symbolic event name. The event is encoded to monitor at the privilege levels
specified by the dfl_plm mask, if supported, otherwise this parameter
is ignored. The operating system specific input and output arguments are
passed in arg.
The event string, str, may contains sub-event masks (umask)
and any other supported modifiers. Only one event is parsed from the string.
For convenience, it is possible to pass a comma-separated list of events in
str but only the first event is encoded.
The following values are supported for os:
- PFM_OS_NONE
- This value causes the event to be encoded purely as specified by the PMU
hardware. The arg argument must be a pointer to a
pfm_pmu_encode_arg_t structure which is defined as follows:
typedef struct {
uint64_t *codes;
char **fstr;
size_t size;
int count;
int idx;
} pfm_pmu_encode_arg_t;
The fields are defined as follows:
- codes
- A pointer to an array of 64-bit values. On input, if codes is NULL,
then the library allocates whatever is necessary to store the encoding of
the event. If codes is not NULL on input, then count must
reflect its actual number of elements. If count is big enough, the
library stores the encoding at the address provided. Otherwise, an error
is returned.
- count
- On input, the field contains the maximum number of elements in the array
codes. Upon return, it contains the number of actual entries in
codes. If codes is NULL, then count must be zero.
- fstr
- If the caller is interested in retrieving the fully qualified event string
where all used unit masks and all modifiers are spelled out, this field
must be set to a non-null address of a pointer to a string (char **). Upon
return, if fstr was not NULL, then the string pointer passed on
entry points to the event string. The string is dynamically allocated and
must eventually be freed by the caller. If fstr was NULL on
entry, then nothing is returned in this field. The typical calling
sequence looks as follows:
char *fstr = NULL
pfm_pmu_encode_arg_t arg;
arg.fstr = &fstr;
ret = pfm_get_os_event_encoding("event",
PFM_PLM0|PFM_PLM3,
PFM_OS_NONE,
&e);
if (ret == PFM_SUCCESS) {
printf("fstr=%s\n", fstr);
free(fstr);
}
- size
- This field contains the size of the struct passed. This field is used to
provide for extensibility of the struct without compromising backward
compatibility. The value should be set to
sizeof(pfm_pmu_encode_arg_t). If instead, a value of 0 is
specified, the library assumes the struct passed is identical to the first
ABI version which size is PFM_RAW_ENCODE_ABI0. Thus, if fields were
added after the first ABI, they will not be set by the library. The
library does check that bytes beyond what is implemented are zeroes.
- idx
- Upon return, this field contains the opaque unique identifier for the
event described in str. This index can be used to retrieve
information about the event using pfm_get_event_info(), for
instance.
- PFM_OS_PERF_EVENT,
PFM_OS_PERF_EVENT_EXT
- This value causes the event to be encoded for the perf_event Linux kernel
interface (available since 2.6.31). The arg must be a pointer to a
pfm_perf_encode_arg_t structure. The PFM_OS_PERF_EVENT layer
provides the modifiers exported by the underlying PMU hardware, some of
which may actually be overridden by the perf_event interface, such as the
monitoring privilege levels. The PFM_OS_PERF_EVENT_EXT extends
PFM_OS_PERF_EVENT to add modifiers controlled only by the
perf_event interface, such as sampling period (period), frequency
(freq) and exclusive resource access (excl).
typedef struct {
struct perf_event_attr *attr;
char **fstr;
size_t size;
int idx;
int cpu;
int flags;
} pfm_perf_encode_arg_t;
The fields are defined as follows:
- attr
- A pointer to a struct perf_event_attr as defined in perf_event.h. This
field cannot be NULL on entry. The struct is not completely overwritten by
the call. The library only modifies the fields it knows about, thereby
allowing perf_event ABI mismatch between caller and library.
- fstr
- Same behavior as is described for PFM_OS_NONE above.
- size
- This field contains the size of the struct passed. This field is used to
provide for extensibility of the struct without compromising backward
compatibility. The value should be set to
sizeof(pfm_perf_encode_arg_t). If instead, a value of 0 is
specified, the library assumes the struct passed is identical to the first
ABI version which size is PFM_PERF_ENCODE_ABI0. Thus, if fields
were added after the first ABI, they will not be set by the library. The
library does check that bytes beyond what is implemented are zeroes.
- idx
- Upon return, this field contains the opaque unique identifier for the
event described in str. This index can be used to retrieve
information about the event using pfm_get_event_info(), for
instance.
- cpu
- Not used yet.
- flags
- Not used yet.
Here is a example of how this function could be used with
PFM_OS_NONE:
#include <inttypes.h>
#include <err.h>
#include <perfmon/pfmlib.h>
int main(int argc, char **argv)
{
pfm_pmu_encode_t arg;
int ret;
ret = pfm_initialize();
if (ret != PFMLIB_SUCCESS)
errx(1, "cannot initialize library %s", pfm_strerror(ret));
memset(&arg, 0, sizeof(arg));
ret = pfm_get_os_event_encoding("RETIRED_INSTRUCTIONS", PFM_PLM3, PFM_OS_NONE, &arg);
if (ret != PFM_SUCCESS)
err(1", cannot get encoding %s", pfm_strerror(ret));
for(i=0; i < arg.count; i++)
printf("count[%d]=0x%"PRIx64"\n", i, arg.codes[i]);
free(arg.codes);
return 0;
}
The function returns in arg the encoding of the event for
the os passed in os. The content of arg depends on the
os argument. Upon success, PFM_SUCCESS is returned otherwise a
specific error code is returned.
Stephane Eranian <eranian@gmail.com>