---
name: "pmAF"
section: "3"
platform: "linux"
package: "pcp"
version: "7.2.2-2"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/pmAF"
---

# pmAF(3)

event queue services for periodic asynchronous callbacks

## NAME

**\_\_pmAFsetup**, **\_\_pmAFregister**, **\_\_pmAFunregister**, **\_\_pmAFblock**, **\_\_pmAFunblock**, **\_\_pmAFisempty** - event queue services for periodic asynchronous callbacks

## C SYNOPSIS

**#include "pmapi.h"**\
 **#include "libpcp.h"**

**int \_\_pmAFsetup(const struct timeval \****start***,** **const struct timeval \****delta***,** **void \****data***,** **void (\****func***)(int, void \*));**\
 **int \_\_pmAFregister(const struct timeval \****delta***,** **void \****data***,** **void (\****func***)(int, void \*));**\
 **int \_\_pmAFunregister(int** *afid***);**\
 **void \_\_pmAFblock(void);**\
 **void \_\_pmAFunblock(void);**\
 **int \_\_pmAFisempty(void);**

**cc ... -lpcp**

## CAVEAT

This documentation is intended for internal Performance Co-Pilot (PCP) developer use.

These interfaces are not part of the PCP APIs that are guaranteed to remain fixed across releases, and they may not work, or may provide different semantics at some point in the future.

## DESCRIPTION

The routines implement an event queue and callback framework that supports periodic evaluation of a series of events with varying frequencies for Performance Co-Pilot (PCP) applications.

The [**pmlogger**(1)](/pmlogger/1.md) application, the [**pmdatrace**(1)](/pmdatrace/1.md) PMDA and the [**pmdahotproc**(1)](/pmdahotproc/1.md) PMDA are the principal users of these services.

An event is created by calling **\_\_pmAFsetup** or **\_\_pmAFregister** and on success the return value is an event number greater than zero. The event has associated event data identified by the opaque pointer *data*. The event will occur with frequency *delta* and each time the event occurs the function *func* will be called with the event number and the event data as arguments.

If **\_\_pmAFsetup** is used then the first event is scheduled for the current time plus *start*, else if **\_\_pmAFregister** is used then the first event is scheduled for the current time plus *delta*.

*func* is called in a SIGALRM signal handler context and so the routines that may be safely called from *func* are restricted to the so-called *async-signal-safe* set. In particular there must be no Standard I/O calls nor calls to any of the [**malloc**(3)](/malloc/3.md) routines to modify the state of the heap. Refer to the *Pointer to a Function* Section of the POSIX.1-2013 document at *https://pubs.opengroup.org/*\
 *onlinepubs/9699919799/functions/V2\_chap02.html* for a more complete description.

The safest and simplest class of *func* routines are those that do minimal processing, set some global state and return. The real work associated with the event is done subsequently from the application's main loop when the global state change is detected.

Once the event occurs and the callback has been executed, the event will be rescheduled for *delta* into the future, except if all the fields of *delta* are zero, in which case the event will not be rescheduled (a \`\`one trip'' event).

Internally, events are processed serially so there is no possibility of nested callbacks or re-entrant callbacks from the event management routines.

Given an event number *afid*, **\_\_pmAFunregister** will permanently remove the corresponding entry from the event queue.

To control the event queue processing, **\_\_pmAFblock** and **\_\_pmAFunblock** may be used to explicitly block and unblock the dispatch of events. This is most useful when the caller wishes to set up a number of events via **\_\_pmAFsetup** or **\_\_pmAFregister** and complete the registration phase before the first event callback occurs.

A call to **\_\_pmAFisempty** returns 1 or 0 depending on whether the event queue is empty or not.

## CAVEATS

These routines rely on [**setitimer**(2)](/setitimer/2.md) and manipulate the handling of **SIGALRM** signals, and hence are probably ill-suited for applications that require direct and concurrent access to these services and resources.

If the callback functions are slow, or delayed, it is possible that the event scheduling could fall behind and never catchup.  When this begins to happen, events are silently skipped and rescheduled at the earliest possible time in the future according to the fixed schedule defined by the time of the call to **\_\_pmAFsetup** and the value of the *start* and *delta* arguments (or defined by the time of the call to **\_\_pmAFregister** and the value of the *delta* argument).

In addition, the semantics of the interval timer(s) and the global state needed to support these services demand that applications calling these routines must do so from a single thread. This restriction is enforced at the [**PMAPI**(3)](/PMAPI/3.md), where routines may return the error code **PM\_ERR\_THREAD** if the library detects calls from more than one thread.

## DIAGNOSTICS

**\_\_pmAFsetup**, **\_\_pmAFregister** and **\_\_pmAFunregister** return values less than zero in the case of an error.  These values are PCP error codes, and may be used to produce error messages via [**pmErrStr**(3)](/pmErrStr/3.md).

The routines support the standard PCP debug tracing, and the **af** option (or **-D af** on the command line) will produce diagnostics on standard error that trace the enqueuing and execution of events.

## SEE ALSO

[**PMAPI**(3)](/PMAPI/3.md)
