2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
25 * IOTimerEventSource.cpp
28 * 2-Feb-1999 Joe Liu (jliu) created.
29 * 1999-10-14 Godfrey van der Linden(gvdl)
30 * Revamped to use thread_call APIs
34 #include <sys/cdefs.h>
37 #include <kern/thread_call.h>
40 #include <IOKit/assert.h>
41 #include <IOKit/system.h>
43 #include <IOKit/IOLib.h>
44 #include <IOKit/IOTimerEventSource.h>
45 #include <IOKit/IOWorkLoop.h>
47 #include <IOKit/IOTimeStamp.h>
49 #define super IOEventSource
50 OSDefineMetaClassAndStructors(IOTimerEventSource
, IOEventSource
)
51 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 0);
52 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 1);
53 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 2);
54 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 3);
55 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 4);
56 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 5);
57 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 6);
58 OSMetaClassDefineReservedUnused(IOTimerEventSource
, 7);
60 bool IOTimerEventSource::checkForWork() { return false; }
62 // Timeout handler function. This function is called by the kernel when
63 // the timeout interval expires.
65 void IOTimerEventSource::timeout(void *self
)
67 IOTimerEventSource
*me
= (IOTimerEventSource
*) self
;
70 Action doit
= (Action
) me
->action
;
73 IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION
),
74 (unsigned int) doit
, (unsigned int) me
->owner
);
76 (*doit
)(me
->owner
, me
);
82 void IOTimerEventSource::setTimeoutFunc()
84 calloutEntry
= (void *) thread_call_allocate((thread_call_func_t
) timeout
,
85 (thread_call_param_t
) this);
88 bool IOTimerEventSource::init(OSObject
*inOwner
, Action inAction
)
90 if (!super::init(inOwner
, (IOEventSource::Action
) inAction
) )
101 IOTimerEventSource::timerEventSource(OSObject
*inOwner
, Action inAction
)
103 IOTimerEventSource
*me
= new IOTimerEventSource
;
105 if (me
&& !me
->init(inOwner
, inAction
)) {
113 void IOTimerEventSource::free()
117 thread_call_free((thread_call_t
) calloutEntry
);
123 void IOTimerEventSource::cancelTimeout()
125 thread_call_cancel((thread_call_t
) calloutEntry
);
126 AbsoluteTime_to_scalar(&abstime
) = 0;
129 void IOTimerEventSource::enable()
132 if (kIOReturnSuccess
!= wakeAtTime(abstime
))
133 super::disable(); // Problem re-scheduling timeout ignore enable
136 void IOTimerEventSource::disable()
138 thread_call_cancel((thread_call_t
) calloutEntry
);
142 IOReturn
IOTimerEventSource::setTimeoutTicks(UInt32 ticks
)
144 return setTimeout(ticks
, NSEC_PER_SEC
/hz
);
147 IOReturn
IOTimerEventSource::setTimeoutMS(UInt32 ms
)
149 return setTimeout(ms
, kMillisecondScale
);
152 IOReturn
IOTimerEventSource::setTimeoutUS(UInt32 us
)
154 return setTimeout(us
, kMicrosecondScale
);
157 IOReturn
IOTimerEventSource::setTimeout(UInt32 interval
, UInt32 scale_factor
)
161 clock_interval_to_deadline(interval
, scale_factor
, &end
);
162 return wakeAtTime(end
);
165 IOReturn
IOTimerEventSource::setTimeout(mach_timespec_t interval
)
167 AbsoluteTime end
, nsecs
;
169 clock_interval_to_absolutetime_interval
170 (interval
.tv_nsec
, kNanosecondScale
, &nsecs
);
171 clock_interval_to_deadline
172 (interval
.tv_sec
, NSEC_PER_SEC
, &end
);
173 ADD_ABSOLUTETIME(&end
, &nsecs
);
175 return wakeAtTime(end
);
178 IOReturn
IOTimerEventSource::setTimeout(AbsoluteTime interval
)
182 clock_get_uptime(&end
);
183 ADD_ABSOLUTETIME(&end
, &interval
);
185 return wakeAtTime(end
);
188 IOReturn
IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks
)
190 return wakeAtTime(ticks
, NSEC_PER_SEC
/hz
);
193 IOReturn
IOTimerEventSource::wakeAtTimeMS(UInt32 ms
)
195 return wakeAtTime(ms
, kMillisecondScale
);
198 IOReturn
IOTimerEventSource::wakeAtTimeUS(UInt32 us
)
200 return wakeAtTime(us
, kMicrosecondScale
);
203 IOReturn
IOTimerEventSource::wakeAtTime(UInt32 abstime
, UInt32 scale_factor
)
206 clock_interval_to_absolutetime_interval(abstime
, scale_factor
, &end
);
208 return wakeAtTime(end
);
211 IOReturn
IOTimerEventSource::wakeAtTime(mach_timespec_t abstime
)
213 AbsoluteTime end
, nsecs
;
215 clock_interval_to_absolutetime_interval
216 (abstime
.tv_nsec
, kNanosecondScale
, &nsecs
);
217 clock_interval_to_absolutetime_interval
218 (abstime
.tv_sec
, kSecondScale
, &end
);
219 ADD_ABSOLUTETIME(&end
, &nsecs
);
221 return wakeAtTime(end
);
224 IOReturn
IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime
)
227 return kIOReturnNoResources
;
230 if ( enabled
&& AbsoluteTime_to_scalar(&abstime
) )
231 thread_call_enter_delayed((thread_call_t
) calloutEntry
, abstime
);
233 return kIOReturnSuccess
;