Mac Developer Library

Developer

pmc.h Reference

Options
Deployment Target:

On This Page

pmc.h Reference

Included Headers

  • <stdint.h>

  • <kern/queue.h>

  • <mach/boolean.h>

  • <mach/mach_time.h>

  • <mach/mach_types.h>

  • <libkern/version.h>

Functions

  • Registers a new performance monitor driver and its associated pointers.

    Declaration

    /* Prevent older AppleProfileFamily kexts from loading on newer kernels. * Alas, C doesn't necessarily have a cleaner way to do the version number concatenation */ #define PERF_REG_NAME1(a, b) a ## b

    Parameters

    monitor

    A handle to the performance monitor driver instance you are registering. Must not be NULL.

    methods

    A filled-in perf_monitor_methods_t structure with version set to MACH_PERFMON_METHODS_VERSION.

    Return Value

    KERN_SUCCESS if the new driver was successfully registered, KERN_INVALID_VALUE if the version of the passed-in perf_monitor_methods_t structure does not match that which is expected, KERN_RESOURCE_SHORTAGE if the kernel lacks the resources to register another performance monitor driver, KERN_INVALID_ARGUMENT if one or both of the arguments is null

    Discussion

    Kexts that implement performance monitor drivers will call this method with a filled-in perf_monitor_methods_t structure (with version set to MACH_PERFMON_METHODS_VERSION). The PMC interface will then register the new driver internally.

  • Unregisters a performance monitor driver and frees space associated with its pointers.

    Declaration

    kern_return_t perf_monitor_unregister( perf_monitor_object_t monitor);

    Parameters

    monitor

    A handle to a performance monitor driver instance that was previously registered with perf_monitor_register

    Return Value

    KERN_SUCCESS if the new driver was successfully unregistered, KERN_INVALID_VALUE if the passed-in perf_monitor_object_t does not match any registered performance monitor, KERN_INVALID_ARGUMENT if the argument is null, KERN_FAILURE if the performance monitor is currently in use.

    Discussion

    Kexts that implement performance monitor drivers will call this method just before they unload to cause the performance monitor they implement to be removed from the kernel's PMC system.

  • Interrupt Threshold Setup

    Declaration

    kern_return_t pmc_config_set_interrupt_threshold( pmc_t pmc, pmc_config_t config, uint64_t threshold, pmc_interrupt_method_t method, void *refCon);

    Discussion

    In order to configure a PMC to use PMI (cause an interrupt after so-many events occur), use this method, and provide a function to be called after the interrupt occurs, along with a reference context. PMC Threshold handler methods will have the pmc that generated the interrupt as the first argument when the interrupt handler is invoked, and the given @refCon (which may be NULL) as the second. This method is not interrupt safe.

  • Setup the configuration

    Declaration

    kern_return_t pmc_config_set_value( pmc_t pmc, pmc_config_t config, uint8_t id, uint64_t value);

    Return Value

    KERN_SUCCESS on success.

    Discussion

    Configurations for counter are architecture-neutral key-value pairs (8bit key, 64bit value). Meanings of the keys and values are defined by the driver-writer and are listed in XML form available for interrogation via the CoreProfile framework. This method is not interrupt safe.

  • Creates a new configuration object for the given pmc.

    Declaration

    kern_return_t pmc_create_config( pmc_t pmc, pmc_config_t *config);

    Parameters

    pmc

    The Perf Counter for which to create a configuration.

    config

    A value-return configuration object.

    Discussion

    This method is not interrupt safe.

  • Finds pmcs by partial string matching.

    Declaration

    kern_return_t pmc_find_by_name( const char *name, pmc_t **pmcs, size_t *pmcCount);

    Parameters

    name

    Partial string to search for.

    pmcs

    Storage for the resultant pmc_t array pointer.

    pmcCount

    Storage for the resultant count of pmc_t's.

    Discussion

    This method returns a list of pmcs (similar to pmc_get_pmc_list) whose names match the given string up to it's length. For example, searching for "ia32" would return pmcs "ia32gp0" and "ia32gp1". Results should be released by the caller using pmc_free_pmc_list

  • Releases a configuration object for the given pmc.

    Declaration

    void pmc_free_config( pmc_t pmc, pmc_config_t config);

    Parameters

    pmc

    The Perf Counter for which to release a configuration.

    config

    A configuration object to be released.

    Discussion

    This method is not interrupt safe.

  • Free a previously allocated list of pmcs.

    Declaration

    void pmc_free_pmc_list( pmc_t *pmcs, size_t pmcCount);

    Parameters

    pmcs

    PMC list to free.

    pmcCount

    Number of pmc_t's in list.

    Discussion

    This method is not interrupt safe.

  • Returns a list of logical cores from which the given pmc can be read from or written to.

    Declaration

    kern_return_t pmc_get_accessible_core_list( pmc_t pmc, uint32_t **logicalCores, size_t *logicalCoreCt);

    Parameters

    pmc

    The PMC for which to return the cores that can read/write it.

    logicalCores

    Storage for the pointer to the list.

    logicalCoreCt

    Value-return number of elements in the returned list. 0 indicates all cores can read/write the given pmc.

    Discussion

    This method can return a NULL list with count of 0 -- this indicates any core can read the given pmc. This method does not allocate the list, therefore callers should take care not to mutate or free the resultant list. This method is interrupt safe.

  • Returns a pointer to the human-readable name of the given pmc.

    Declaration

    const char *pmc_get_name( pmc_t pmc);

    Parameters

    pmc

    The PMC whose name should be returned.

    Discussion

    The returned pointer is not a copy, and does not need to be freed. This method is interrupt safe.

  • Returns an allocated list of all pmc_t's known to the kernel.

    Declaration

    kern_return_t pmc_get_pmc_list( pmc_t **pmcs, size_t *pmcCount);

    Parameters

    pmcs

    Storage for the resultant pmc_t array pointer.

    pmcCount

    Storage for the resultant count of pmc_t's.

    Discussion

    Callers should free the resultant list via pmc_free_pmc_list. This method is not interrupt safe.

  • Register a new Performance Counter, and attach it to the given Performance Monitor

    Declaration

    kern_return_t pmc_register( perf_monitor_object_t monitor, pmc_object_t pmc, pmc_methods_t *methods, void *object);

    Parameters

    monitor

    A handle to a Performance Monitor that was previously registered.

    pmc

    A handle to the Performance Counter instance to be attached to the monitor object

    methods

    A filled-in pmc_methods_t structure with version set to MACH_PMC_METHODS_VERSION

    object

    an Object to be used during the open() and close() methods. Must be a subclass of IOService, cannot be NULL.

    Return Value

    KERN_SUCCESS if the new counter was successfully registered and attached, KERN_INVALID_VALUE if the version of the passed-in pmc_methods_t structure does not match that which is expected, KERN_RESOURCE_SHORTAGE if the kernel lacks the resources to register another performance counter instance, KERN_INVALID_ARGUMENT if any of the arguments is null

    Discussion

    This method takes a Performance Monitor driver instance that was previously registered with perf_monitor_register, and attaches an instance of a Performance Counter that will be accessed with the given set of pmc methods.

  • Free a reservation and all associated resources.

    Declaration

    kern_return_t pmc_reservation_free( pmc_reservation_t reservation);

    Parameters

    reservation

    The reservation to free

    Discussion

    This method will free the resources associated with the given reservation and release the associated PMC back to general availability. If the reservation is currently counting, it will be stopped prior to release. This method is not interrupt safe.

  • Read the counter value

    Declaration

    kern_return_t pmc_reservation_read( pmc_reservation_t reservation, uint64_t *value);

    Parameters

    reservation

    The reservation whose value to read.

    value

    Value-return event count

    Discussion

    This method will read the event count associated with the given reservation. If the pmc is currently on hardware, and the caller is currently ] executing in a context that both a) matches the reservation's context, and b) can access the reservation's pmc directly, the value will be read directly from the hardware. Otherwise, the value stored in the reservation is returned. This method is interrupt safe. If the caller is calling from outside of interrupt context, this method may block.

  • Start counting

    Declaration

    kern_return_t pmc_reservation_start( pmc_reservation_t reservation);

    Parameters

    reservation

    The reservation to start counting

    Discussion

    This method instructs the given reservation to start counting as soon as possible. If the reservation is for a thread (or task) other than the current thread, or for a pmc that is not accessible from the current logical core, the reservation will start counting the next time the thread (or task) runs on a logical core than can access the pmc. This method is interrupt safe. If this method is called from outside of interrupt context, it may block.

  • Stop counting

    Declaration

    kern_return_t pmc_reservation_stop( pmc_reservation_t reservation);

    Parameters

    reservation

    The reservation to stop counting

    Discussion

    This method instructs the given reservation to stop counting as soon as possible. If the reservation is for a thread (or task) other than the current thread, or for a pmc that is not accessible from the current logical core, the reservation will stop counting the next time the thread (or task) c eases to run on a logical core than can access the pmc. This method is interrupt safe. If called form outside of interrupt context, this method may block.

  • Write the counter value

    Declaration

    kern_return_t pmc_reservation_write( pmc_reservation_t reservation, uint64_t value);

    Parameters

    reservation

    The reservation to write.

    value

    The event count to write

    Discussion

    This method will write the event count associated with the given reservation. If the pmc is currently on hardware, and the caller is currently executing in a context that both a) matches the reservation's context, and b) can access the reservation's pmc directly, the value will be written directly to the hardware. Otherwise, the value stored in the reservation is overwritten. This method is interrupt safe. If the caller is calling from outside of interrupt context, this method may block.

  • Reserve a PMC for System-wide counting.

    Declaration

    kern_return_t pmc_reserve( pmc_t pmc, pmc_config_t config, pmc_reservation_t *reservation);

    Parameters

    pmc

    The PMC to reserve.

    config

    The configuration object to use with the given pmc.

    reservation

    A value-return reservation object to be used in pmc_reservation_* methods.

    Return Value

    This method will return one of the following values: KERN_SUCCESS: The given pmc was successfully reserved in system-scope; the given config object has been consumed and should not be freed by the caller, KERN_FAILURE: The given pmc is already reserved in a conflicting scope, KERN_INVALID_ARGUMENT: All three arguments are required to be non-NULL, but at least one is NULL, KERN_RESOURCE_SHORTAGE: Could not allocate a new reservation object.

    Discussion

    This method will attempt to reserve the given pmc at system-scope. It will configure the given pmc to count the event indicated by the given configuration object. This method consumes the given configuration object if the return value is KERN_SUCCESS - any other return value indicates the caller should free the configuration object via pmc_free_config. This method is not interrupt safe.

  • Reserve a PMC for task-wide counting.

    Declaration

    kern_return_t pmc_reserve_task( pmc_t pmc, pmc_config_t config, task_t task, pmc_reservation_t *reservation);

    Parameters

    pmc

    The PMC to reserve

    config

    The configuration object to use.

    task

    The task for which to enable the counter.

    reservation

    A value-return reservation object.

    Return Value

    See pmc_reserve

    Discussion

    This method will attempt to reserve the given pmc for task-wide counting. The resulting reservation will only count when the task is running on one of the logical cores that can read the given pmc. The semantics of this method are the same as pmc_reserve in all other respects.

  • Reserve a PMC for thread-wide counting.

    Declaration

    kern_return_t pmc_reserve_thread( pmc_t pmc, pmc_config_t config, thread_t thread, pmc_reservation_t *reservation);

    Parameters

    pmc

    The PMC to reserve

    config

    The configuration object to use.

    thread

    The thread for which to enable the counter.

    reservation

    A value-return reservation object.

    Return Value

    See pmc_reserve

    Discussion

    This method will attempt to reserve the given pmc for thread-wide counting. The resulting reservation will only count when the thread is running on one of the logical cores that can read the given pmc. The semantics of this method are the same as pmc_reserve_task in all other respects.

  • Unregisters a Performance Counter

    Declaration

    kern_return_t pmc_unregister( perf_monitor_object_t monitor, pmc_object_t pmc);

    Parameters

    monitor

    The registered Performance Monitor from which to remove a pmc.

    pmc

    The Performance Counter to unregister.

    Return Value

    KERN_SUCCESS if the counter was successfully unregistered, KERN_INVALID_VALUE if the passed-in pmc_object_t does not match any registered performance counter, KERN_INVALID_ARGUMENT if any argument is null, KERN_FAILURE if the performance counter is currently in use.

    Discussion

    Does the reverse of pmc_register.

Callbacks

  • A pointer to a method that disables a set of counters.

    Declaration

    typedef kern_return_t ( *perfmon_disable_counters_method_t)( perf_monitor_object_t pm, pmc_object_t *pmcs, uint32_t pmcCount);

    Discussion

    Implementations of this method type must be safe to call at interrupt context. See perfmon_enable_counters_method_t

  • A pointer to a method that enables a set of counters.

    Declaration

    typedef kern_return_t ( *perfmon_enable_counters_method_t)( perf_monitor_object_t pm, pmc_object_t *pmcs, uint32_t pmcCount);

    Parameters

    pmcs

    An array of pmc_object_t instances (non-NULL).

    pmcCount

    The number of elements in the @pmcs array.

    Return Value

    KERN_SUCCESS upon successful global enable of the given counters (may return IOKit error codes).

    Discussion

    Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that will set the method to be called when the counter threshold is reached.

    Declaration

    typedef kern_return_t ( *pmc_config_set_interrupt_threshold_handler_method_t)( pmc_config_object_t config, void *target, pmc_interrupt_method_t method, void *refCon);

    Parameters

    config

    A configuration object.

    target

    A reference pointer used as the first argument to the callback method.

    method

    A pointer to the method to be called.

    refCon

    A reference pointer to be used as the second argument to the callback method (may be NULL).

    Discussion

    typedef

  • A pointer to a method that will set the counter PMI threshold.

    Declaration

    typedef kern_return_t ( *pmc_config_set_interrupt_threshold_method_t)( pmc_config_object_t config, uint64_t threshold);

    Parameters

    config

    A configuration object

    threshold

    The number of events after which to cause an interrupt callback.

    Discussion

    typedef

  • A pointer to a method to set a key-value pair on a config object.

    Declaration

    typedef kern_return_t ( *pmc_config_set_value_method_t)( pmc_config_object_t config, uint8_t id, uint64_t value);

    Parameters

    config

    Pointer to config object.

    id

    8-bit integer ID (determined by the driver).

    value

    64-bit integer value (interpretted by the driver).

    Return Value

    KERN_SUCCESS on success, KERN_FAILURE on bad value, KERN_INVALID_ARGUMENT on bad id

    Discussion

    Configuration objects take key-value pairs for setting various bits in the pmc configs Corresponds to IOPerformanceCounterConfiguration::setValueForId() method.

  • A pointer to a method that creates a configuration object for a counter

    Declaration

    typedef pmc_config_object_t ( *pmc_create_config_method_t)( pmc_object_t pmc);

    Parameters

    pmc

    A valid pmc object

    Return Value

    NULL on failure, or a pmc_config_t on success.

    Discussion

    Configuration objects create and hold the hardware representation for a set of driver-defined key-value pairs. Corresponds to IOPerformanceCounter::createConfiguration() method.

  • A pointer to a method that disables the counter hardware for a given PMC.

    Declaration

    typedef kern_return_t ( *pmc_disable_method_t)( pmc_object_t pmc);

    Parameters

    pmc

    A valid pmc object.

    Return Value

    KERN_SUCCESS on successful disable

    Discussion

    A pointer to a method that disables the counter hardware for a given PMC. Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that enables the counter hardware for a given PMC.

    Declaration

    typedef kern_return_t ( *pmc_enable_method_t)( pmc_object_t pmc);

    Parameters

    pmc

    A valid pmc object.

    Return Value

    KERN_SUCCESS on successful enable

    Discussion

    A pointer to a method that enables the counter hardware for a given PMC. Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method to free a configuration object for a pmc

    Declaration

    typedef void ( *pmc_free_config_method_t)( pmc_object_t pmc, pmc_config_object_t config);

    Parameters

    pmc

    The pmc object used to create the config

    config

    The config object to release

    Discussion

    Method should free a pmc config object created with a pmc_create_config_method_t above

  • A pointer to a method that returns an array of the logical cores from which a PMC can be accessed.

    Declaration

    typedef kern_return_t ( *pmc_get_accessible_cores_method_t)( pmc_object_t pmc, uint32_t **cores, size_t *coreCt);

    Parameters

    pmc

    A valid pmc object

    cores

    A value-returned array of logical cores that can access the given PMC.

    coreCt

    A value-return count of the number of entries in the @cores array.

    Return Value

    KERN_SUCCESS on success, KERN_FAILURE otherwise.

    Discussion

    A pointer to a method that returns an array of the logical cores from which a PMC can be accessed. Resulting array of cores should not be released by xnu. Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that attempts to read the count from the given counter hardware.

    Declaration

    typedef kern_return_t ( *pmc_get_count_method_t)( pmc_object_t pmc, uint64_t *value);

    Parameters

    pmc

    The counter from which to read

    value

    Storage for the counter's hardware value.

    Discussion

    Implementations of this method type must be safe to call from interrupt context. *

  • A pointer to a method that returns the Performance Monitor Object for a counter

    Declaration

    typedef perf_monitor_object_t ( *pmc_get_monitor_method_t)( pmc_object_t pmc);

    Parameters

    pmc

    A valid pmc object

    Return Value

    NULL on failure, or a perf_monitor_object_t on success.

    Discussion

    A pointer to a method that returns the Performance Monitor Object for a counter. Implementations of this method type must be safe to call at interrupt context. Corresponds to IOPerformanceCounter::getMonitor() method.

  • A pointer to a method that returns the registered name of the PMC.

    Declaration

    typedef const char *( *pmc_get_name_method_t)( pmc_object_t pmc);

    Parameters

    pmc

    A valid pmc object.

    Return Value

    NULL on failure, or a pointer to the registered name of the pmc.

    Discussion

    A pointer to a method that returns the registered name of the PMC. Corresponds to IOPerformanceCounter::getRegisteredName() method.

    NOTE: Driver authors must not allocate or copy the string during this method: it may be called from interrupt context or with spin locks held.

  • A pointer to a method that will be called when a Performance Counter causes a PMI interrupt

    Declaration

    typedef void ( *pmc_interrupt_method_t)( void *target, void *refCon);

    Parameters

    target

    The pmc_reservation_t that caused the interrupt

    refCon

    Any value as defined by the end-user who called pmc_config_set_interrupt_threshold

    Discussion

    Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that returns if a pmc is accessible from a given logical core.

    Declaration

    typedef boolean_t ( *pmc_is_accessible_from_logical_core_method_t)( pmc_object_t pmc, uint32_t core);

    Parameters

    pmc

    A valid pmc object.

    core

    The logical core number.

    Return Value

    TRUE if the pmc can be read in the execution context of the given logical core, FALSE otherwise.

    Discussion

    A pointer to a method that returns if a pmc is accessible from a given logical core. Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that will configure a pmc's control registers according to the given configuration object.

    Declaration

    typedef kern_return_t ( *pmc_set_config_method_t)( pmc_object_t pmc, pmc_config_object_t config);

    Parameters

    pmc

    The pmc reference object.

    config

    A configuration object.

    Discussion

    Implementations of this method type must be safe to call at interrupt context.

  • A pointer to a method that attempts to write the count to the given counter hardware.

    Declaration

    typedef kern_return_t ( *pmc_set_count_method_t)( pmc_object_t pmc, uint64_t value);

    Parameters

    pmc

    The counter to which to write.

    value

    The value to write to the hardware.

    Discussion

    Implementations of this method type must be safe to call from interrupt context.

Data Types

See the Overview section above for header-level documentation.

  • A set of method pointers to be used when interacting with a performance monitor object

    Declaration

    typedef struct perf_monitor_methods { uint32_t perf_monitor_methods_version; // Always set to MACH_PERFMON_METHODS_VERSION when writing driver kexts uint32_t flags; perfmon_get_accessible_cores_method_t accessible_cores; perfmon_enable_counters_method_t enable_counters; perfmon_disable_counters_method_t disable_counters; perfmon_on_idle_method_t on_idle; perfmon_on_idle_exit_method_t on_idle_exit; } perf_monitor_methods_t;

    Discussion

    This structure is the set of driver-implemented callback methods to be used when interacting with a new performance monitor from the kernel.

    Import Statement

  • In-kernel object to track a driver-implemented performance monitor.

    Declaration

    typedef struct perf_monitor { /* * A reference-pointer used as the first argument to all callback methods * (to seamlessly work with C++ objects). This is the same value that was * used in the perf_monitor_register() method. */ perf_monitor_object_t object; // Copy of the pointers used to interact with the above instance perf_monitor_methods_t methods; // reference counted uint32_t useCount; uint32_t reservedCounters; // A value of -1 here indicates independence from a particular core int cpu; // links to other perf monitors queue_chain_t link; queue_chain_t cpu_link; }*perf_monitor_t;

    Discussion

    struct perf_monitor

    Import Statement

  • Performance Counter Registration methods.

    Declaration

    typedef struct pmc_methods { uint32_t pmc_methods_version; // Always set to MACH_PMC_METHODS_VERSION in your driver. // All methods are required. pmc_create_config_method_t create_config; pmc_free_config_method_t free_config; pmc_config_set_value_method_t config_set_value; pmc_config_set_interrupt_threshold_method_t config_set_threshold; pmc_config_set_interrupt_threshold_handler_method_t config_set_handler; pmc_set_config_method_t set_config; pmc_get_monitor_method_t get_monitor; pmc_get_name_method_t get_name; pmc_is_accessible_from_logical_core_method_t accessible_from_core; pmc_get_accessible_cores_method_t accessible_cores; pmc_get_count_method_t get_count; pmc_set_count_method_t set_count; pmc_disable_method_t disable; pmc_enable_method_t enable; pmc_open_method_t open; pmc_close_method_t close; } pmc_methods_t;

    Discussion

    This structure represents a set of driver-implemented methods to be used by the kernel when interacting with the associated performance counter. Since a Performance Monitor may implement any number of distinct types of Performance Counters, each counter registers with its own set of callback methods.

    Import Statement

  • Performance Counter Registration methods.

    Declaration

    typedef struct pmc_methods { uint32_t pmc_methods_version; // Always set to MACH_PMC_METHODS_VERSION in your driver. // All methods are required. pmc_create_config_method_t create_config; pmc_free_config_method_t free_config; pmc_config_set_value_method_t config_set_value; pmc_config_set_interrupt_threshold_method_t config_set_threshold; pmc_config_set_interrupt_threshold_handler_method_t config_set_handler; pmc_set_config_method_t set_config; pmc_get_monitor_method_t get_monitor; pmc_get_name_method_t get_name; pmc_is_accessible_from_logical_core_method_t accessible_from_core; pmc_get_accessible_cores_method_t accessible_cores; pmc_get_count_method_t get_count; pmc_set_count_method_t set_count; pmc_disable_method_t disable; pmc_enable_method_t enable; pmc_open_method_t open; pmc_close_method_t close; } pmc_methods_t;

    Discussion

    This structure represents a set of driver-implemented methods to be used by the kernel when interacting with the associated performance counter. Since a Performance Monitor may implement any number of distinct types of Performance Counters, each counter registers with its own set of callback methods.

    Import Statement

  • In-kernel object to track an individual driver-implemented performance counter

    Declaration

    typedef struct pmc { /* * A reference-pointer used as the first argument to all callback methods * (to seamlessly work with C++ objects). This is the same value that was * used in the pmc_register() method. */ pmc_object_t object; /* Copy of the pointers used to interact with the above instance */ pmc_methods_t methods; /* Object to be used during open/close methods */ void *open_object; /* reference counted */ uint32_t useCount; /* link to parent */ perf_monitor_t monitor; /* link to other PMCs */ queue_chain_t link; }*pmc_t;

    Discussion

    struct pmc

    Import Statement

  • In-kernel object to track an individual reservation

    Declaration

    struct pmc_reservation { pmc_t pmc; // Pointer to in-kernel pmc which is reserved pmc_config_t config; // counter configuration // stored counter value uint64_t value; // TODO: Add mach-port (user- export object?) volatile uint32_t flags __attribute__(( aligned (4))); volatile pmc_state_t state __attribute__(( aligned (4))); volatile uint32_t active_last_context_in __attribute__(( aligned (4))); union { task_t task; // not retained thread_t thread; // not retained }; queue_chain_t link; };

    Discussion

    struct pmc_reservation