#include <IOKit/IOEventSource.h>
#include <IOKit/IOInterruptEventSource.h>
#include <IOKit/IOCommandGate.h>
+#include <IOKit/IOCommandPool.h>
#include <IOKit/IOTimeStamp.h>
#include <IOKit/IOKitDebug.h>
#include <libkern/OSDebug.h>
#define IOStatisticsOpenGate() \
do { \
IOStatistics::countWorkLoopOpenGate(reserved->counter); \
+ if (reserved->lockInterval) lockTime(); \
} while(0)
-
#define IOStatisticsCloseGate() \
do { \
- IOStatistics::countWorkLoopCloseGate(reserved->counter); \
+ IOStatistics::countWorkLoopCloseGate(reserved->counter); \
+ if (reserved->lockInterval) reserved->lockTime = mach_absolute_time(); \
} while(0)
#define IOStatisticsAttachEventSource() \
IOReturn IOWorkLoop::addEventSource(IOEventSource *newEvent)
{
+ if ((workThread)
+ && !thread_has_thread_name(workThread)
+ && (newEvent->owner)
+ && !OSDynamicCast(IOCommandPool, newEvent->owner)) {
+ thread_set_thread_name(workThread, newEvent->owner->getMetaClass()->getClassName());
+ }
+
return controlG->runCommand((void *) mAddEvent, (void *) newEvent);
}
return result;
}
+
+void
+IOWorkLoop::lockTime(void)
+{
+ uint64_t time;
+ time = mach_absolute_time() - reserved->lockTime;
+ if (time > reserved->lockInterval)
+ {
+ absolutetime_to_nanoseconds(time, &time);
+ if (kTimeLockPanics & reserved->options) panic("IOWorkLoop %p lock time %qd us", this, time / 1000ULL);
+ else OSReportWithBacktrace("IOWorkLoop %p lock time %qd us", this, time / 1000ULL);
+ }
+}
+
+void
+IOWorkLoop::setMaximumLockTime(uint64_t interval, uint32_t options)
+{
+ IORecursiveLockLock(gateLock);
+ reserved->lockInterval = interval;
+ reserved->options = (reserved->options & ~kTimeLockPanics) | (options & kTimeLockPanics);
+ IORecursiveLockUnlock(gateLock);
+}