LIBPFM(3)

πŸ’– LIBPFM πŸ’–

okay so bestie, welcome to the libpfm page β€” that's the Linux Programmer's Manual corner of the universe, and today's main character is one very specific little function. pull up a chair, grab a strawberry πŸ“, we're doing this.


✨ NAME ✨

pfm_get_pmu_info β€” get PMU information. that's it, that's the whole vibe. πŸ‘‘


🌸 SYNOPSIS 🌸

#include <perfmon/pfmlib.h>

int pfm_get_pmu_info(pfm_pmu_t pmu, pfm_pmu_info_t *info);

πŸ¦‹ DESCRIPTION πŸ¦‹

so like. this function hands you back, inside info, all the tea about a PMU model β€” and you tell it which PMU you're asking about by passing its identifier in pmu. simple as that. 🫢

the pfm_pmu_info structure is defined like this, and yes you need to see the whole thing:

typedef struct {
        const char              *name;
        const char              *desc;
        pfm_pmu_t               pmu;
        pfm_pmu_type_t          type;
        int                     size;
        int                     nevents;
        int                     first_event;
        int                     max_encoding;
        int                     num_cntrs;
        int                     num_fixed_cntrs;
        struct {
                int             is_present:1;
                int             is_arch_default:1;
                int             is_core:1;
                int             is_uncore:1;
                int             reserved:28;
        };
} pfm_pmu_info_t;

and now, field by field, because we do NOT skip the details in this house:

  • name β€” the symbolic name of the PMU. you can literally use this name as a prefix in an event string. it's a read-only string, so hands off, don't touch. πŸ™…
  • desc β€” the description of the PMU. also read-only. also don't touch.
  • pmu β€” the unique PMU identification code. it's identical to the value you passed in pmu; it's only here for completeness, i.e. it's giving "I'm just here so I don't get fined." πŸ’…
  • type β€” what kind of PMU this is. these are the types that exist:
    • PFM_PMU_TYPE_UNKNOWN β€” couldn't figure out the type of the PMU. mystery era. πŸ’€
    • PFM_PMU_TYPE_CORE β€” this field is set to one when the PMU is implemented by the processor core.
    • PFM_PMU_TYPE_UNCORE β€” this field is set to one when the PMU is implemented on the processor die but at the socket level, i.e., capturing events for all cores. socket-level behavior, very demure, very mindful.
  • nevents β€” how many events are available for this PMU model, based on the host processor. only valid if is_present is set to 1, okay? and no cap: event identifiers are not guaranteed contiguous. like, just because nevents equals 100 does not mean event identifiers run from 0 to 99. so you have to use the iterator function pfm_get_event_next() to go from one identifier to the next. do not freestyle this. πŸ™ˆ
  • first_event β€” the opaque index of the first event for this PMU model. you can use that index with the pfm_get_event_info() or pfm_get_event_next() functions. if no event is available at all, this field contains -1. sad girl hours. 😭
  • num_cntrs β€” how many generic counters the PMU supports. a counter is generic if it can count more than one event. when it's not possible to determine the number of generic counters, this field contains -1.
  • num_fixed_cntrs β€” how many fixed counters the PMU supports. a counter is fixed if it's hardwired to count only one event. when it's not possible to determine the number of generic counters, this field contains -1.
  • size β€” the size of the struct you passed. this field exists so the struct can grow in the future without breaking backward compatibility β€” iconic forward-thinking behavior honestly. you should set the value to sizeof(pfm_pmu_info_t). if instead you specify a value of 0, the library assumes the struct you passed is identical to the first ABI version, whose size is PFM_PMU_INFO_ABI0. so if fields were added after that first ABI, the library will not set them for you. also, the library does check that bytes beyond what's implemented are zeroes. it's thorough like that. ⭐
  • max_encoding β€” how many event codes are returned by pfm_get_event_encoding().
  • is_present β€” set to one if the PMU model has been detected on the host system. πŸŽ€
  • is_dfl β€” set to one if the PMU is the default PMU for this architecture. otherwise this field is zero.

πŸ”₯ RETURN πŸ”₯

if everything goes right, the function returns PFM_SUCCESS and drops the PMU information into info. if not, it returns an error code. that's the whole deal. ✨


πŸ’€ ERRORS πŸ’€

  • PFMLIB_ERR_NOINIT β€” the library has not been initialized properly. bestie. initialize it.
  • PFMLIB_ERR_NOTSUPP β€” the PMU model is not supported by the library. it's just not that girl, we move on.
  • PFMLIB_ERR_INVAL β€” the pmu argument is invalid, or info is NULL, or size is not zero. fix ur inputs. 🫠

🌈 SEE ALSO 🌈


πŸ‘‘ AUTHOR πŸ‘‘

Stephane Eranian <eranian@gmail.com> β€” absolute legend, wrote this whole thing, we stan. πŸ’œ


and that's the page!! this was the libpfm manual, dating all the way back to December, 2009 β€” vintage, retro, still slaying. take care of urself, go count some events, and remember: read the struct before you write the struct. mwah. πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from