---
name: "pfm_get_os_event_encoding"
section: "3"
platform: "linux"
package: "libpfm"
version: "4.14.1-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/pfm_get_os_event_encoding"
---

# pfm\_get\_os\_event\_encoding(3)

get event encoding for a specific operating system

## NAME

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

## SYNOPSIS

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

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

```

## 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**

  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_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

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

- **PFM\_ERR\_TOOSMALL**

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

- **PFM\_ERR\_INVAL**

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

- **PFM\_ERR\_NOMEM**

  Not enough memory.

- **PFM\_ERR\_NOTFOUND**

  Event not found.

- **PFM\_ERR\_ATTR**

  Invalid event attribute (unit mask or modifier)

- **PFM\_ERR\_ATTR\_VAL**

  Invalid modifier value.

- **PFM\_ERR\_ATTR\_SET**

  attribute already set, cannot be changed.

- **PFM\_ERR\_ATTR\_UMASK**

  Missing unit mask.

- **PFM\_ERR\_ATTR\_FEATCOMB**

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

## AUTHOR

Stephane Eranian \<eranian@gmail.com\>
