#include <sys/sysctl.h>
#include <kern/host.h>
+#include <kern/zalloc.h>
#include <IOKit/system.h>
#include <libkern/c++/OSKext.h>
#include <IOKit/IOKitDebug.h>
#if IOKITSTATS
-
bool IOStatistics::enabled = false;
uint32_t IOStatistics::sequenceID = 0;
return;
}
-#if DEVELOPMENT || DEBUG
- /* Always enabled in development and debug builds. */
-#else
- /* Only enabled in release builds if the boot argument is set. */
+ /* Only enabled if the boot argument is set. */
if (!(kIOStatistics & gIOKitDebug)) {
return;
}
-#endif
sysctl_register_oid(&sysctl__debug_iokit_statistics_general);
sysctl_register_oid(&sysctl__debug_iokit_statistics_workloop);
IOWorkLoopCounter *wlc;
IOUserClientProcessEntry *uce;
- /* Free up the list of counters */
+ /* Disconnect workloop counters; cleanup takes place in unregisterWorkLoop() */
while ((wlc = SLIST_FIRST(&found->workLoopList))) {
SLIST_REMOVE_HEAD(&found->workLoopList, link);
- kfree(wlc, sizeof(IOWorkLoopCounter));
+ wlc->parentKext = NULL;
}
/* Free up the user client list */
}
IORWLockWrite(lock);
-
- SLIST_REMOVE(&counter->parentKext->workLoopList, counter, IOWorkLoopCounter, link);
+ if (counter->parentKext) {
+ SLIST_REMOVE(&counter->parentKext->workLoopList, counter, IOWorkLoopCounter, link);
+ }
kfree(counter, sizeof(IOWorkLoopCounter));
registeredWorkloops--;
uint32_t i;
KextNode *found = NULL, *ke = NULL;
- btCount = OSBacktrace(bt, btCount);
+ /*
+ * Gathering the backtrace is a significant source of
+ * overhead. OSBacktrace does many safety checks that
+ * are not needed in this situation.
+ */
+ btCount = fastbacktrace((uintptr_t*)bt, btCount);
if (write) {
IORWLockWrite(lock);
/* Ignore first levels */
scanAddr = (vm_offset_t *)&bt[btMin - 1];
- for (i = 0; i < btCount; i++, scanAddr++) {
+ for (i = btMin - 1; i < btCount; i++, scanAddr++) {
ke = RB_ROOT(&kextAddressHead);
while (ke) {
if (*scanAddr < ke->address) {