LIBPFM(3)

πŸ“¦
version 4.14.1 Β· 2 versions
, in arch rolling, centos-stream 10, centos-stream 9, debian trixie, fedora 43, fedora 44, nixos 26.05, nixpkgs unstable, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ¦‹ LIBPFM(3) πŸ¦‹

okay bestie, welcome to the Linux Programmer's Manual, and this one is LIBPFM(3) β€” the manual page for pfm_get_os_event_encoding. yes that is the whole title, we're being efficient. πŸ’…


✨ NAME ✨

pfm_get_os_event_encoding β€” get event encoding for a specific operating system. that's it, that's the job. πŸŽ€


🌸 SYNOPSIS 🌸

#include <perfmon/pfmlib.h>

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

πŸ’œ DESCRIPTION πŸ’œ

So this is THE function. the main character, fr fr. πŸ‘‘

It's the key function you call to retrieve the encoding of an event for a specific operating system interface. The event string you pass in str gets parsed and encoded for the operating system you specified in os. And here's the thing β€” only one event per call can be encoded. So str can contain only one symbolic event name. That's the vibe. πŸ™ˆ

The event gets encoded to monitor at the privilege levels specified by the dfl_plm mask β€” if supported, otherwise this parameter is just ignored, no big deal, it's not mad at you. The operating system specific input and output arguments get passed in arg.

The event string str may contain sub-event masks (umask) and any other supported modifiers. Only one event is parsed from the string. And for convenience (iconic behaviour tbh), it is possible to pass a comma-separated list of events in str β€” but only the first event is encoded. don't @ me, that's just how it is. 😭

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. no exceptions bestie.

⭐ 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. slay.


🫢 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. cute and considerate of it honestly.

⭐ fstr

Same behavior as is described for PFM_OS_NONE above. (scroll up bestie 🫢)

⭐ 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. (it's giving "we'll get to it" 🫠)

⭐ flags

Not used yet. (same energy 🫠)


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. that's the vibe check. ✨


πŸŽ€ ERRORS πŸŽ€

  • PFM_ERR_TOOSMALL β€” The code argument is too small for the encoding. not enough room bestie 😭
  • PFM_ERR_INVAL β€” The code or count argument is NULL or the str contains more than one symbolic event. one event at a time, periodt.
  • PFM_ERR_NOMEM β€” Not enough memory. πŸ’€
  • PFM_ERR_NOTFOUND β€” Event not found. she's not here πŸ‘»
  • 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. nope, not happening πŸ™…β€β™€οΈ

πŸ‘‘ AUTHOR πŸ‘‘

Stephane Eranian <eranian@gmail.com> β€” the icon, the legend, the moment. 🫢


and that's the whole page bestie!! πŸ’– this came from the Linux Programmer's Manual, LIBPFM(3), dated January, 2011 β€” yes she's vintage, she's still serving, and honestly? she ate. 🌸 no cap. πŸ¦‹βœ¨