Loading...
--- xnu/xnu-124.1/iokit/Kernel/IOTimerEventSource.cpp
+++ xnu/xnu-792.6.61/iokit/Kernel/IOTimerEventSource.cpp
@@ -57,6 +57,11 @@
OSMetaClassDefineReservedUnused(IOTimerEventSource, 6);
OSMetaClassDefineReservedUnused(IOTimerEventSource, 7);
+//
+// reserved != 0 means IOTimerEventSource::timeoutAndRelease is being used,
+// not a subclassed implementation.
+//
+
bool IOTimerEventSource::checkForWork() { return false; }
// Timeout handler function. This function is called by the kernel when
@@ -66,22 +71,59 @@
{
IOTimerEventSource *me = (IOTimerEventSource *) self;
- if (me->enabled) {
- Action doit = (Action) me->action;
-
- if (doit) {
- IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
- (unsigned int) doit, (unsigned int) me->owner);
- me->closeGate();
- (*doit)(me->owner, me);
- me->openGate();
+ if (me->enabled && me->action)
+ {
+ IOWorkLoop *
+ wl = me->workLoop;
+ if (wl)
+ {
+ Action doit;
+ wl->closeGate();
+ doit = (Action) me->action;
+ if (doit && me->enabled && AbsoluteTime_to_scalar(&me->abstime))
+ {
+ IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
+ (unsigned int) doit, (unsigned int) me->owner);
+ (*doit)(me->owner, me);
+ }
+ wl->openGate();
}
}
}
+void IOTimerEventSource::timeoutAndRelease(void * self, void * count)
+{
+ IOTimerEventSource *me = (IOTimerEventSource *) self;
+
+ if (me->enabled && me->action)
+ {
+ IOWorkLoop *
+ wl = me->reserved->workLoop;
+ if (wl)
+ {
+ Action doit;
+ wl->closeGate();
+ doit = (Action) me->action;
+ if (doit && (me->reserved->calloutGeneration == (SInt32) count))
+ {
+ IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
+ (unsigned int) doit, (unsigned int) me->owner);
+ (*doit)(me->owner, me);
+ }
+ wl->openGate();
+ }
+ }
+
+ me->reserved->workLoop->release();
+ me->release();
+}
+
void IOTimerEventSource::setTimeoutFunc()
{
- calloutEntry = (void *) thread_call_allocate((thread_call_func_t) timeout,
+ // reserved != 0 means IOTimerEventSource::timeoutAndRelease is being used,
+ // not a subclassed implementation
+ reserved = IONew(ExpansionData, 1);
+ calloutEntry = (void *) thread_call_allocate((thread_call_func_t) &IOTimerEventSource::timeoutAndRelease,
(thread_call_param_t) this);
}
@@ -103,7 +145,7 @@
IOTimerEventSource *me = new IOTimerEventSource;
if (me && !me->init(inOwner, inAction)) {
- me->free();
+ me->release();
return 0;
}
@@ -117,13 +159,23 @@
thread_call_free((thread_call_t) calloutEntry);
}
+ if (reserved)
+ IODelete(reserved, ExpansionData, 1);
+
super::free();
}
void IOTimerEventSource::cancelTimeout()
{
- thread_call_cancel((thread_call_t) calloutEntry);
+ if (reserved)
+ reserved->calloutGeneration++;
+ bool active = thread_call_cancel((thread_call_t) calloutEntry);
AbsoluteTime_to_scalar(&abstime) = 0;
+ if (active && reserved)
+ {
+ release();
+ workLoop->release();
+ }
}
void IOTimerEventSource::enable()
@@ -135,13 +187,20 @@
void IOTimerEventSource::disable()
{
- thread_call_cancel((thread_call_t) calloutEntry);
+ if (reserved)
+ reserved->calloutGeneration++;
+ bool active = thread_call_cancel((thread_call_t) calloutEntry);
super::disable();
+ if (active && reserved)
+ {
+ release();
+ workLoop->release();
+ }
}
IOReturn IOTimerEventSource::setTimeoutTicks(UInt32 ticks)
{
- return setTimeout(ticks, NSEC_PER_SEC/hz);
+ return setTimeout(ticks, kTickScale);
}
IOReturn IOTimerEventSource::setTimeoutMS(UInt32 ms)
@@ -187,7 +246,7 @@
IOReturn IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks)
{
- return wakeAtTime(ticks, NSEC_PER_SEC/hz);
+ return wakeAtTime(ticks, kTickScale);
}
IOReturn IOTimerEventSource::wakeAtTimeMS(UInt32 ms)
@@ -200,25 +259,32 @@
return wakeAtTime(us, kMicrosecondScale);
}
-IOReturn IOTimerEventSource::wakeAtTime(UInt32 abstime, UInt32 scale_factor)
+IOReturn IOTimerEventSource::wakeAtTime(UInt32 inAbstime, UInt32 scale_factor)
{
AbsoluteTime end;
- clock_interval_to_absolutetime_interval(abstime, scale_factor, &end);
-
- return wakeAtTime(end);
-}
-
-IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t abstime)
+ clock_interval_to_absolutetime_interval(inAbstime, scale_factor, &end);
+
+ return wakeAtTime(end);
+}
+
+IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t inAbstime)
{
AbsoluteTime end, nsecs;
clock_interval_to_absolutetime_interval
- (abstime.tv_nsec, kNanosecondScale, &nsecs);
+ (inAbstime.tv_nsec, kNanosecondScale, &nsecs);
clock_interval_to_absolutetime_interval
- (abstime.tv_sec, kSecondScale, &end);
+ (inAbstime.tv_sec, kSecondScale, &end);
ADD_ABSOLUTETIME(&end, &nsecs);
return wakeAtTime(end);
+}
+
+void IOTimerEventSource::setWorkLoop(IOWorkLoop *inWorkLoop)
+{
+ super::setWorkLoop(inWorkLoop);
+ if ( enabled && AbsoluteTime_to_scalar(&abstime) && workLoop )
+ wakeAtTime(abstime);
}
IOReturn IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime)
@@ -227,8 +293,24 @@
return kIOReturnNoResources;
abstime = inAbstime;
- if ( enabled && AbsoluteTime_to_scalar(&abstime) )
- thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
+ if ( enabled && AbsoluteTime_to_scalar(&abstime) && workLoop )
+ {
+ if (reserved)
+ {
+ retain();
+ workLoop->retain();
+ reserved->workLoop = workLoop;
+ reserved->calloutGeneration++;
+ if (thread_call_enter1_delayed((thread_call_t) calloutEntry,
+ (void *) reserved->calloutGeneration, abstime))
+ {
+ release();
+ workLoop->release();
+ }
+ }
+ else
+ thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
+ }
return kIOReturnSuccess;
}