LIBPFM(3) Linux Programmer's Manual LIBPFM(3)

# [NAME](#NAME)

pfm\_get\_os\_event\_encoding - get event encoding for a specific operating system

# [SYNOPSIS](#SYNOPSIS)

```
#include <perfmon/pfmlib.h>

int pfm_get_os_event_encoding(const char *str, int dfl_plm, pfm_os_t os,  void *arg);

```

# [DESCRIPTION](#DESCRIPTION)

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**](#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**](#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**](#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**](#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**](#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**](#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**](#PFM_OS_PERF_EVENT,)

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**](#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**](#fstr~2)

Same behavior as is described for PFM\_OS\_NONE above.

[**size**](#size~2)

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**](#idx~2)

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**](#cpu)

Not used yet.

[**flags**](#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_arg_t arg;


   int i, ret;


   ret = pfm_initialize();


   if (ret != PFM_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;
}
```

# [RETURN](#RETURN)

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.

# [ERRORS](#ERRORS)

[**PFM\_ERR\_TOOSMALL**](#PFM_ERR_TOOSMALL)

The **code** argument is too small for the encoding.

[**PFM\_ERR\_INVAL**](#PFM_ERR_INVAL)

The **code** or **count** argument is **NULL** or the **str** contains more than one symbolic event.

[**PFM\_ERR\_NOMEM**](#PFM_ERR_NOMEM)

Not enough memory.

[**PFM\_ERR\_NOTFOUND**](#PFM_ERR_NOTFOUND)

Event not found.

[**PFM\_ERR\_ATTR**](#PFM_ERR_ATTR)

Invalid event attribute (unit mask or modifier)

[**PFM\_ERR\_ATTR\_VAL**](#PFM_ERR_ATTR_VAL)

Invalid modifier value.

[**PFM\_ERR\_ATTR\_SET**](#PFM_ERR_ATTR_SET)

attribute already set, cannot be changed.

[**PFM\_ERR\_ATTR\_UMASK**](#PFM_ERR_ATTR_UMASK)

Missing unit mask.

[**PFM\_ERR\_ATTR\_FEATCOMB**](#PFM_ERR_ATTR_FEATCOMB)

Unit masks or features cannot be combined into a single event.

# [AUTHOR](#AUTHOR)

Stephane Eranian &lt;eranian@gmail.com&gt;

January, 2011

---

Document: pfm_get_os_event_encoding(3) from libpfm 4.14.1-r0 (Chainguard OS)
Source: https://git.code.sf.net/p/perfmon2/libpfm4
