]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOWorkLoop.cpp
xnu-3789.60.24.tar.gz
[apple/xnu.git] / iokit / Kernel / IOWorkLoop.cpp
index d2c28b04391aa89c968d6a38801f766e2d89c4e1..e3896d38b19398722fa938bfdefb9a049dcfa51f 100644 (file)
 #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>
+#include <kern/thread.h>
 
 #define super OSObject
 
@@ -83,11 +85,12 @@ do { \
 #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() \
@@ -126,11 +129,7 @@ bool IOWorkLoop::init()
                
                bzero(reserved,sizeof(ExpansionData));
        }
-       
-#if DEBUG
-       OSBacktrace ( reserved->allocationBacktrace, sizeof ( reserved->allocationBacktrace ) / sizeof ( reserved->allocationBacktrace[0] ) );
-#endif
-       
+
     if ( gateLock == NULL ) {
         if ( !( gateLock = IORecursiveLockAlloc()) )
             return false;
@@ -143,11 +142,6 @@ bool IOWorkLoop::init()
         workToDo = false;
     }
 
-    if (!reserved) {
-        reserved = IONew(ExpansionData, 1);
-        reserved->options = 0;
-    }
-       
     IOStatisticsRegisterCounter();
 
     if ( controlG == NULL ) {
@@ -177,6 +171,7 @@ bool IOWorkLoop::init()
             return false;
     }
 
+    (void) thread_set_tag(workThread, THREAD_TAG_IOWORKLOOP);
     return true;
 }
 
@@ -258,6 +253,7 @@ void IOWorkLoop::free()
        // Either way clean up all of our resources and return.
        
        if (controlG) {
+           controlG->workLoop = 0;
            controlG->release();
            controlG = 0;
        }
@@ -285,6 +281,13 @@ void IOWorkLoop::free()
 
 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);
 }
     
@@ -562,10 +565,10 @@ IOReturn IOWorkLoop::_maintRequest(void *inC, void *inD, void *, void *)
                                if (eventChain == inEvent)
                                        eventChain = inEvent->getNext();
                                else {
-                                       IOEventSource *event, *next;
+                                       IOEventSource *event, *next = 0;
                
                                        event = eventChain;
-                                       while ((next = event->getNext()) && next != inEvent)
+                                       if (event) while ((next = event->getNext()) && (next != inEvent))
                                                event = next;
                
                                        if (!next) {
@@ -579,10 +582,10 @@ IOReturn IOWorkLoop::_maintRequest(void *inC, void *inD, void *, void *)
                                if (passiveEventChain == inEvent)
                                        passiveEventChain = inEvent->getNext();
                                else {
-                                       IOEventSource *event, *next;
+                                       IOEventSource *event, *next = 0;
                
                                        event = passiveEventChain;
-                                       while ((next = event->getNext()) && next != inEvent)
+                                       if (event) while ((next = event->getNext()) && (next != inEvent))
                                                event = next;
                
                                        if (!next) {
@@ -643,3 +646,25 @@ IOWorkLoop::eventSourcePerformsWork(IOEventSource *inEventSource)
        
     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);
+}