#include <IOKit/IOReportMacros.h>
IOKit/IOReportMacros.h
macroIOREPORT_ABORT
#define IOREPORT_ABORT panic
macroSIMPLEREPORT_BUFSIZE
#define SIMPLEREPORT_BUFSIZE (sizeof(IOReportElement))
macroSIMPLEREPORT_INIT
#define SIMPLEREPORT_INIT(buf, bufSize, providerID, channelID, cats) do {
memset((buf), '&', (bufSize));
IOReportElement *__elem = (IOReportElement *)(buf);
IOSimpleReportValues *__vals;
if ((bufSize) >= SIMPLEREPORT_BUFSIZE) {
__elem->provider_id = (providerID);
__elem->channel_id = (channelID);
__elem->channel_type.report_format = kIOReportFormatSimple;
__elem->channel_type.reserved = 0;
__elem->channel_type.categories = (cats);
__elem->channel_type.nelements = 1;
__elem->channel_type.element_idx = 0;
__elem->timestamp = 0;
__vals = (IOSimpleReportValues*)&__elem->values;
__vals->simple_value = kIOReportInvalidIntValue;
}
else {
IOREPORT_ABORT("bufSize is smaller than the required size\n");
}
} while(0)macroSIMPLEREPORT_SETVALUE
#define SIMPLEREPORT_SETVALUE(simp_buf, new_value) do {
IOReportElement *__elem = (IOReportElement *)(simp_buf);
IOSimpleReportValues *__vals;
__vals = (IOSimpleReportValues*)&__elem->values;
__vals->simple_value = (new_value);
} while(0)macroSIMPLEREPORT_INCREMENTVALUE
Increment the value of a SimpleReport.
void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
int64_t increment - amount by which to increment the value
#define SIMPLEREPORT_INCREMENTVALUE(simp_buf, increment_by) do {
IOReportElement *__elem = (IOReportElement *)(simp_buf);
IOSimpleReportValues *__vals;
__vals = (IOSimpleReportValues*)&__elem->values;
int64_t __simple_value = INT64_MAX;
if (os_add_overflow(__vals->simple_value, (increment_by), &__simple_value)) {
__vals->simple_value = INT64_MAX;
} else {
__vals->simple_value = __simple_value;
}
} while(0)macroSIMPLEREPORT_UPDATEPREP
#define SIMPLEREPORT_UPDATEPREP(simp_buf, ptr2cpy, size2cpy) do {
(ptr2cpy) = (simp_buf);
(size2cpy) = sizeof(IOReportElement);
} while(0)macroSIMPLEREPORT_UPDATERES
#define SIMPLEREPORT_UPDATERES(action, result) do {
if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
int *__nElements = (int *)(result);
*__nElements += 1;
}
} while (0)macroSIMPLEREPORT_GETCHID
#define SIMPLEREPORT_GETCHID(simp_buf) (((IOReportElement *)(simp_buf))->channel_id)
macroSIMPLEREPORT_GETCHTYPE
#define SIMPLEREPORT_GETCHTYPE(simp_buf) (*(uint64_t*)&(((IOReportElement *)(simp_buf))->channel_type))
macroSIMPLEREPORT_GETVALUE
#define SIMPLEREPORT_GETVALUE(simp_buf) (((IOSimpleReportValues*)&(((IOReportElement*)(simp_buf))->values)) ->simple_value)
structIOStateReportInfo
Internal struct for StateReport
| uint16_t | curr_state | |
| uint64_t | update_ts | |
| IOReportElement[] | elem | Array of elements |
typedefIOStateReportInfo
typedef struct IOStateReportInfo IOStateReportInfo;
macroSTATEREPORT_BUFSIZE
Determine the size required for a StateReport buffer.
int nstates - number of states to be reported
#define STATEREPORT_BUFSIZE(nstates) (sizeof(IOStateReportInfo) + (nstates) * sizeof(IOReportElement))
macroSTATEREPORT_INIT
Initialize a StateReport buffer.
uint16_t nstates - number of states to be reported
void* buffer - ptr to STATEREPORT_BUFSIZE(nstates) bytes
size_t bufSize - sanity check of buffer's size
uint64_t providerID - registry Entry ID of the reporting service
uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
IOReportCategories categories - categories of this channel
If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
If that returns, the buffer is left full of '&'.
#define STATEREPORT_INIT(nstates, buf, bufSize, providerID, channelID, cats) do {
memset((buf), '&', (bufSize));
IOStateReportInfo *__info = (IOStateReportInfo *)(buf);
IOStateReportValues *__rep;
IOReportElement *__elem;
if ((bufSize) >= STATEREPORT_BUFSIZE(nstates)) {
for (uint16_t __no = 0; __no < (nstates); __no++) {
__elem = &(__info->elem[__no]);
__rep = (IOStateReportValues *) &(__elem->values);
__elem->provider_id = (providerID);
__elem->channel_id = (channelID);
__elem->channel_type.report_format = kIOReportFormatState;
__elem->channel_type.reserved = 0;
__elem->channel_type.categories = (cats);
__elem->channel_type.nelements = (nstates);
__elem->channel_type.element_idx = __no;
__elem->timestamp = 0;
__rep->state_id = __no;
__rep->intransitions = 0;
__rep->upticks = 0;
__rep->last_intransition = 0;
}
__info->curr_state = 0;
__info->update_ts = 0;
}
else {
IOREPORT_ABORT("bufSize is smaller than the required size\n");
}
} while(0)macroSTATEREPORT_SETSTATEID
Initialize the state id field of a state with the specified value. By
default, STATEREPORT_INIT() initializes the state IDs with the index of
that state. This macro can be used to provide a more descriptive state id.
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
unsigned stateIdx - index of the state, out of bounds -> no-op
uint64_t stateID - new state id, see IOREPORT_MAKEID()
#define STATEREPORT_SETSTATEID(state_buf, stateIdx, stateID) do {
IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
IOStateReportValues *__rep;
if ((stateIdx) < __info->elem[0].channel_type.nelements) {
__rep = (IOStateReportValues*) &(__info->elem[(stateIdx)].values);
__rep->state_id = (stateID);
}
} while (0)macroSTATEREPORT_SETSTATE
Set the state of a StateReport.
void* state_buf - pointer to memory initialized by STATEREPORT_INIT()
unsigned newStateIdx - index of new state, out of bounds -> no-op
uint64_t changeTime - time at which the transition occurred
#define STATEREPORT_SETSTATE(state_buf, newStateIdx, changeTime) do {
IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
IOStateReportValues *__rep;
if ((newStateIdx) < __info->elem[0].channel_type.nelements ) {
__rep = (IOStateReportValues*) &(__info->elem[__info->curr_state].values);
if (__info->update_ts)
__rep->upticks += (changeTime) - __info->update_ts;
__info->elem[(newStateIdx)].timestamp = (changeTime);
__rep = (IOStateReportValues*) &(__info->elem[(newStateIdx)].values);
__rep->intransitions++;
__info->curr_state = (newStateIdx);
__info->update_ts = (changeTime);
}
} while(0)macroSTATEREPORT_UPDATEPREP
Prepare a StateReport for
IOService::updateReport(kIOReportCopyChannelData...)
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
uint64_t currentTime - current timestamp
void* ptr2cpy - filled in with pointer to buffer to be copied out
size_t size2cpy - filled in with the size of the buffer to copy out
#define STATEREPORT_UPDATEPREP(state_buf, currentTime, ptr2cpy, size2cpy) do {
IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
IOReportElement *__elem;
IOStateReportValues *__state;
(size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement);
(ptr2cpy) = (void *) &__info->elem[0];
if (__info->update_ts) {
__elem = &__info->elem[__info->curr_state];
__state = (IOStateReportValues *)&__elem->values;
__elem->timestamp = (currentTime);
__state->upticks += (currentTime) - __info->update_ts;
__info->update_ts = (currentTime);
}
} while(0)macroSTATEREPORT_UPDATERES
#define STATEREPORT_UPDATERES(state_buf, action, result) do {
IOStateReportInfo *__info = (IOStateReportInfo *)(state_buf);
IOReportElement *__elem;
int *__nElements = (int *)(result);
if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
__elem = &(__info->elem[0]);
if (os_add_overflow(*__nElements, __elem->channel_type.nelements, __nElements)) {
*__nElements = INT_MAX;
}
}
} while (0)macroSTATEREPORT_GETCHID
Get the 64-bit channel ID of a StateReport.
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
#define STATEREPORT_GETCHID(state_buf) (((IOStateReportInfo *)(state_buf))->elem[0].channel_id)
macroSTATEREPORT_GETCHTYPE
Get the IOReportChannelType of a StateReport.
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
#define STATEREPORT_GETCHTYPE(state_buf) (*(uint64_t*)&(((IOStateReportInfo *)(state_buf))->elem[0].channel_type))
macroSTATEREPORT_GETTRANSITIONS
Get the number of transitions into a given state.
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
#define STATEREPORT_GETTRANSITIONS(state_buf, stateIdx) (((stateIdx) < ((IOStateReportInfo *)(state_buf))->elem[0].channel_type.nelements) ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->intransitions : kIOReportInvalidValue)
macroSTATEREPORT_GETTICKS
Get the total number of ticks spent in a given state.
void* state_buf - ptr to memory initialized by STATEREPORT_INIT()
unsigned stateIdx - index of state, out of bounds -> kIOReportInvalidValue
#define STATEREPORT_GETTICKS(state_buf, stateIdx) (((stateIdx) < ((IOStateReportInfo*)(state_buf))->elem[0].channel_type.nelements) ? ((IOStateReportValues*)&(((IOStateReportInfo*)(state_buf))->elem[(stateIdx)].values))->upticks : kIOReportInvalidValue)
macroSIMPLEARRAY_BUFSIZE
#define SIMPLEARRAY_BUFSIZE(nValues) ((((nValues)/IOR_VALUES_PER_ELEMENT) + (((nValues) % IOR_VALUES_PER_ELEMENT) ? 1:0)) * sizeof(IOReportElement))
macroSIMPLEARRAY_INIT
#define SIMPLEARRAY_INIT(nValues, buf, bufSize, providerID, channelID, cats) do {
memset((buf), '&', (bufSize));
IOSimpleArrayReportValues *__rep;
IOReportElement *__elem;
uint32_t __nElems = (((nValues) / IOR_VALUES_PER_ELEMENT) +
(((nValues) % IOR_VALUES_PER_ELEMENT) ? 1 : 0));
if ((bufSize) >= SIMPLEARRAY_BUFSIZE(nValues)) {
for (unsigned __no = 0; __no < __nElems; __no++) {
__elem = &(((IOReportElement *)(buf))[__no]);
__rep = (IOSimpleArrayReportValues *) &(__elem->values);
__elem->provider_id = (providerID);
__elem->channel_id = (channelID);
__elem->channel_type.report_format = kIOReportFormatSimpleArray;
__elem->channel_type.reserved = 0;
__elem->channel_type.categories = (cats);
__elem->channel_type.nelements = (__nElems);
__elem->channel_type.element_idx = __no;
__elem->timestamp = 0;
__rep->simple_values[0] = kIOReportInvalidIntValue;
__rep->simple_values[1] = kIOReportInvalidIntValue;
__rep->simple_values[2] = kIOReportInvalidIntValue;
__rep->simple_values[3] = kIOReportInvalidIntValue;
}
}
else {
IOREPORT_ABORT("bufSize is smaller than the required size\n");
}
} while(0)macroSIMPLEARRAY_SETVALUE
Set a value at a specified index in a SimpleArrayReport.
void* array_bufbuf - ptr to memory initialized by SIMPLEARRAY_INIT()
unsigned idx - array index, out of bounds -> no-op
uint64_t newValue - new value to be stored at array[idx]
#define SIMPLEARRAY_SETVALUE(array_buf, idx, newValue) do {
__SA_FINDREP((array_buf), (idx))
__rep->simple_values[__valueIdx] = (newValue);
}
} while(0)macroSIMPLEARRAY_INCREMENTVALUE
Increment an array value within a SimpleArrayReport.
void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
unsigned idx - array index to increment, out of bounds -> no-op
int64_t value - amount by which to increment array[idx]
#define SIMPLEARRAY_INCREMENTVALUE(array_buf, idx, value) do {
__SA_FINDREP((array_buf), (idx))
if (os_add_overflow(__rep->simple_values[__valueIdx], (value), &__rep->simple_values[__valueIdx])) {
__rep->simple_values[__valueIdx] = INT64_MAX;
}
}
} while(0)macroSIMPLEARRAY_UPDATEPREP
#define SIMPLEARRAY_UPDATEPREP(array_buf, ptr2cpy, size2cpy) do {
IOReportElement *__elem;
__elem = &(((IOReportElement *)(array_buf))[0]);
(ptr2cpy) = (void *) (array_buf);
(size2cpy) = __elem->channel_type.nelements * sizeof(IOReportElement);
} while(0)macroSIMPLEARRAY_UPDATERES
#define SIMPLEARRAY_UPDATERES(array_buf, action, result) do {
IOReportElement *__elem;
int *__nElements = (int *)(result);
__elem = &(((IOReportElement *)(array_buf))[0]);
if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
if (os_add_overflow(*__nElements, __elem->channel_type.nelements, __nElements)) {
*__nElements = INT_MAX;
}
}
} while (0)macroSIMPLEARRAY_GETCHID
Get the 64-bit channel ID of a SimpleArrayReport.
void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
#define SIMPLEARRAY_GETCHID(array_buf) (((IOReportElement *)(array_buf))->channel_id)
macroSIMPLEARRAY_GETCHTYPE
Get the IOReportChannelType of a SimpleArrayReport.
void* simp_buf - ptr to memory initialized by SIMPLEREPORT_INIT()
#define SIMPLEARRAY_GETCHTYPE(array_buf) (*(uint64_t*)&(((IOReportElement *)(array_buf))->channel_type))
macroSIMPLEARRAY_GETVALUE
Get a value from a SimpleArrayReport.
void* array_buf - ptr to memory initialized by SIMPLEARRAY_INIT()
unsigned idx - index of the value, out of bounds -> kIOReportInvalidValue
#define SIMPLEARRAY_GETVALUE(array_buf, idx) (((idx) > __SA_MAXINDEX(array_buf) || (idx) < 0) ? kIOReportInvalidIntValue : ((IOSimpleArrayReportValues*)&( ((IOReportElement*)(array_buf))[(idx) / IOR_VALUES_PER_ELEMENT].values)) ->simple_values[(idx) % IOR_VALUES_PER_ELEMENT])
structIOHistReportInfo
Internal struct for HistogramReport
| int | bucketWidth | |
| IOReportElement[] | elem | Array of elements |
typedefIOHistReportInfo
typedef struct IOHistReportInfo IOHistReportInfo;
macroHISTREPORT_BUFSIZE
Determine the size required for a HistogramReport buffer.
int nbuckets - number of buckets in the histogram
#define HISTREPORT_BUFSIZE(nbuckets) (sizeof(IOHistReportInfo) + ((nbuckets) * sizeof(IOReportElement)))
macroHISTREPORT_INIT
Initialize a HistogramReport buffer. Supports only linear scale histogram.
uint16_t nbuckets - number of buckets data is combined into
uint32_t bucketWidth - size of each bucket
void* buffer - ptr to HISTREPORT_BUFSIZE(nbuckets) bytes
size_t bufSize - sanity check of buffer's size
uint64_t providerID - registry Entry ID of the reporting service
uint64_t channelID - ID of this channel, see IOREPORT_MAKEID()
IOReportCategories categories - categories of this channel
If the buffer is not of sufficient size, the macro invokes IOREPORT_ABORT.
If that returns, the buffer is left full of '&'.
#define HISTREPORT_INIT(nbuckets, bktSize, buf, bufSize, providerID, channelID, cats) do {
memset((buf), '&', (bufSize));
IOHistReportInfo *__info = (IOHistReportInfo *)(buf);
IOReportElement *__elem;
IOHistogramReportValues *__rep;
if ((bufSize) >= HISTREPORT_BUFSIZE(nbuckets)) {
__info->bucketWidth = (bktSize);
for (uint16_t __no = 0; __no < (nbuckets); __no++) {
__elem = &(__info->elem[__no]);
__rep = (IOHistogramReportValues *) &(__elem->values);
__elem->provider_id = (providerID);
__elem->channel_id = (channelID);
__elem->channel_type.report_format = kIOReportFormatHistogram;
__elem->channel_type.reserved = 0;
__elem->channel_type.categories = (cats);
__elem->channel_type.nelements = (nbuckets);
__elem->channel_type.element_idx = __no;
__elem->timestamp = 0;
memset(__rep, '\0', sizeof(IOHistogramReportValues));
}
}
else {
IOREPORT_ABORT("bufSize is smaller than the required size\n");
}
} while (0)macroHISTREPORT_TALLYVALUE
Update histogram with a new value.
void* hist_buf - pointer to memory initialized by HISTREPORT_INIT()
int64_t value - new value to add to the histogram
#define HISTREPORT_TALLYVALUE(hist_buf, value) do {
IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf);
IOReportElement *__elem;
IOHistogramReportValues *__rep;
for (unsigned __no = 0; __no < __info->elem[0].channel_type.nelements; __no++) {
if ((value) <= __info->bucketWidth * (__no+1)) {
__elem = &(__info->elem[__no]);
__rep = (IOHistogramReportValues *) &(__elem->values);
if (__rep->bucket_hits == 0) {
__rep->bucket_min = __rep->bucket_max = (value);
}
else if ((value) < __rep->bucket_min) {
__rep->bucket_min = (value);
}
else if ((value) > __rep->bucket_max) {
__rep->bucket_max = (value);
}
int64_t __sum = 0;
if (os_add_overflow(__rep->bucket_sum, (value), &__sum)) {
__rep->bucket_sum = INT64_MAX;
} else {
__rep->bucket_sum = __sum;
}
__rep->bucket_hits++;
break;
}
}
} while (0)macroHISTREPORT_UPDATEPREP
#define HISTREPORT_UPDATEPREP(hist_buf, ptr2cpy, size2cpy) do {
IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf);
(size2cpy) = __info->elem[0].channel_type.nelements * sizeof(IOReportElement);
(ptr2cpy) = (void *) &__info->elem[0];
} while(0)macroHISTREPORT_UPDATERES
#define HISTREPORT_UPDATERES(hist_buf, action, result) do {
IOHistReportInfo *__info = (IOHistReportInfo *)(hist_buf);
int *__nElements = (int *)(result);
if (((action) == kIOReportGetDimensions) || ((action) == kIOReportCopyChannelData)) {
if (os_add_overflow(*__nElements, __info->elem[0].channel_type.nelements, __nElements)) {
*__nElements = INT_MAX;
}
}
} while (0)macroHISTREPORT_GETCHID
Get the 64-bit channel ID of a HistogramReport.
void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
#define HISTREPORT_GETCHID(hist_buf) (((IOHistReportInfo *)(hist_buf))->elem[0].channel_id)
macroHISTREPORT_GETCHTYPE
Get the IOReportChannelType of a HistogramReport.
void* hist_buf - ptr to memory initialized by HISTREPORT_INIT()
#define HISTREPORT_GETCHTYPE(hist_buf) (*(uint64_t*)&(((IOHistReportInfo *)(hist_buf))->elem[0].channel_type))