]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOTimerEventSource.cpp
xnu-517.tar.gz
[apple/xnu.git] / iokit / Kernel / IOTimerEventSource.cpp
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
27 *
28 * IOTimerEventSource.cpp
29 *
30 * HISTORY
31 * 2-Feb-1999 Joe Liu (jliu) created.
32 * 1999-10-14 Godfrey van der Linden(gvdl)
33 * Revamped to use thread_call APIs
34 *
35 */
36
37#include <sys/cdefs.h>
38
39__BEGIN_DECLS
40#include <kern/thread_call.h>
41__END_DECLS
42
43#include <IOKit/assert.h>
44#include <IOKit/system.h>
45
46#include <IOKit/IOLib.h>
47#include <IOKit/IOTimerEventSource.h>
48#include <IOKit/IOWorkLoop.h>
49
50#include <IOKit/IOTimeStamp.h>
51
52#define super IOEventSource
53OSDefineMetaClassAndStructors(IOTimerEventSource, IOEventSource)
54OSMetaClassDefineReservedUnused(IOTimerEventSource, 0);
55OSMetaClassDefineReservedUnused(IOTimerEventSource, 1);
56OSMetaClassDefineReservedUnused(IOTimerEventSource, 2);
57OSMetaClassDefineReservedUnused(IOTimerEventSource, 3);
58OSMetaClassDefineReservedUnused(IOTimerEventSource, 4);
59OSMetaClassDefineReservedUnused(IOTimerEventSource, 5);
60OSMetaClassDefineReservedUnused(IOTimerEventSource, 6);
61OSMetaClassDefineReservedUnused(IOTimerEventSource, 7);
62
63bool IOTimerEventSource::checkForWork() { return false; }
64
65// Timeout handler function. This function is called by the kernel when
66// the timeout interval expires.
67//
68void IOTimerEventSource::timeout(void *self)
69{
70 IOTimerEventSource *me = (IOTimerEventSource *) self;
71
72 if (me->enabled) {
73 Action doit = (Action) me->action;
74
75 if (doit) {
76 IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
77 (unsigned int) doit, (unsigned int) me->owner);
78 me->closeGate();
79 (*doit)(me->owner, me);
80 me->openGate();
81 }
82 }
83}
84
85void IOTimerEventSource::setTimeoutFunc()
86{
87 calloutEntry = (void *) thread_call_allocate((thread_call_func_t) timeout,
88 (thread_call_param_t) this);
89}
90
91bool IOTimerEventSource::init(OSObject *inOwner, Action inAction)
92{
93 if (!super::init(inOwner, (IOEventSource::Action) inAction) )
94 return false;
95
96 setTimeoutFunc();
97 if (!calloutEntry)
98 return false;
99
100 return true;
101}
102
103IOTimerEventSource *
104IOTimerEventSource::timerEventSource(OSObject *inOwner, Action inAction)
105{
106 IOTimerEventSource *me = new IOTimerEventSource;
107
108 if (me && !me->init(inOwner, inAction)) {
55e303ae 109 me->release();
1c79356b
A
110 return 0;
111 }
112
113 return me;
114}
115
116void IOTimerEventSource::free()
117{
118 if (calloutEntry) {
119 cancelTimeout();
120 thread_call_free((thread_call_t) calloutEntry);
121 }
122
123 super::free();
124}
125
126void IOTimerEventSource::cancelTimeout()
127{
128 thread_call_cancel((thread_call_t) calloutEntry);
129 AbsoluteTime_to_scalar(&abstime) = 0;
130}
131
132void IOTimerEventSource::enable()
133{
134 super::enable();
135 if (kIOReturnSuccess != wakeAtTime(abstime))
136 super::disable(); // Problem re-scheduling timeout ignore enable
137}
138
139void IOTimerEventSource::disable()
140{
141 thread_call_cancel((thread_call_t) calloutEntry);
142 super::disable();
143}
144
145IOReturn IOTimerEventSource::setTimeoutTicks(UInt32 ticks)
146{
147 return setTimeout(ticks, NSEC_PER_SEC/hz);
148}
149
150IOReturn IOTimerEventSource::setTimeoutMS(UInt32 ms)
151{
152 return setTimeout(ms, kMillisecondScale);
153}
154
155IOReturn IOTimerEventSource::setTimeoutUS(UInt32 us)
156{
157 return setTimeout(us, kMicrosecondScale);
158}
159
160IOReturn IOTimerEventSource::setTimeout(UInt32 interval, UInt32 scale_factor)
161{
162 AbsoluteTime end;
163
164 clock_interval_to_deadline(interval, scale_factor, &end);
165 return wakeAtTime(end);
166}
167
168IOReturn IOTimerEventSource::setTimeout(mach_timespec_t interval)
169{
170 AbsoluteTime end, nsecs;
171
172 clock_interval_to_absolutetime_interval
173 (interval.tv_nsec, kNanosecondScale, &nsecs);
174 clock_interval_to_deadline
175 (interval.tv_sec, NSEC_PER_SEC, &end);
176 ADD_ABSOLUTETIME(&end, &nsecs);
177
178 return wakeAtTime(end);
179}
180
181IOReturn IOTimerEventSource::setTimeout(AbsoluteTime interval)
182{
183 AbsoluteTime end;
184
185 clock_get_uptime(&end);
186 ADD_ABSOLUTETIME(&end, &interval);
187
188 return wakeAtTime(end);
189}
190
191IOReturn IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks)
192{
193 return wakeAtTime(ticks, NSEC_PER_SEC/hz);
194}
195
196IOReturn IOTimerEventSource::wakeAtTimeMS(UInt32 ms)
197{
198 return wakeAtTime(ms, kMillisecondScale);
199}
200
201IOReturn IOTimerEventSource::wakeAtTimeUS(UInt32 us)
202{
203 return wakeAtTime(us, kMicrosecondScale);
204}
205
206IOReturn IOTimerEventSource::wakeAtTime(UInt32 abstime, UInt32 scale_factor)
207{
208 AbsoluteTime end;
209 clock_interval_to_absolutetime_interval(abstime, scale_factor, &end);
210
211 return wakeAtTime(end);
212}
213
214IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t abstime)
215{
216 AbsoluteTime end, nsecs;
217
218 clock_interval_to_absolutetime_interval
219 (abstime.tv_nsec, kNanosecondScale, &nsecs);
220 clock_interval_to_absolutetime_interval
221 (abstime.tv_sec, kSecondScale, &end);
222 ADD_ABSOLUTETIME(&end, &nsecs);
223
224 return wakeAtTime(end);
225}
226
227IOReturn IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime)
228{
229 if (!action)
230 return kIOReturnNoResources;
231
232 abstime = inAbstime;
233 if ( enabled && AbsoluteTime_to_scalar(&abstime) )
234 thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
235
236 return kIOReturnSuccess;
237}