]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOTimerEventSource.cpp
xnu-201.42.3.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 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22/*
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * IOTimerEventSource.cpp
26 *
27 * HISTORY
28 * 2-Feb-1999 Joe Liu (jliu) created.
29 * 1999-10-14 Godfrey van der Linden(gvdl)
30 * Revamped to use thread_call APIs
31 *
32 */
33
34#include <sys/cdefs.h>
35
36__BEGIN_DECLS
37#include <kern/thread_call.h>
38__END_DECLS
39
40#include <IOKit/assert.h>
41#include <IOKit/system.h>
42
43#include <IOKit/IOLib.h>
44#include <IOKit/IOTimerEventSource.h>
45#include <IOKit/IOWorkLoop.h>
46
47#include <IOKit/IOTimeStamp.h>
48
49#define super IOEventSource
50OSDefineMetaClassAndStructors(IOTimerEventSource, IOEventSource)
51OSMetaClassDefineReservedUnused(IOTimerEventSource, 0);
52OSMetaClassDefineReservedUnused(IOTimerEventSource, 1);
53OSMetaClassDefineReservedUnused(IOTimerEventSource, 2);
54OSMetaClassDefineReservedUnused(IOTimerEventSource, 3);
55OSMetaClassDefineReservedUnused(IOTimerEventSource, 4);
56OSMetaClassDefineReservedUnused(IOTimerEventSource, 5);
57OSMetaClassDefineReservedUnused(IOTimerEventSource, 6);
58OSMetaClassDefineReservedUnused(IOTimerEventSource, 7);
59
60bool IOTimerEventSource::checkForWork() { return false; }
61
62// Timeout handler function. This function is called by the kernel when
63// the timeout interval expires.
64//
65void IOTimerEventSource::timeout(void *self)
66{
67 IOTimerEventSource *me = (IOTimerEventSource *) self;
68
69 if (me->enabled) {
70 Action doit = (Action) me->action;
71
72 if (doit) {
73 IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
74 (unsigned int) doit, (unsigned int) me->owner);
75 me->closeGate();
76 (*doit)(me->owner, me);
77 me->openGate();
78 }
79 }
80}
81
82void IOTimerEventSource::setTimeoutFunc()
83{
84 calloutEntry = (void *) thread_call_allocate((thread_call_func_t) timeout,
85 (thread_call_param_t) this);
86}
87
88bool IOTimerEventSource::init(OSObject *inOwner, Action inAction)
89{
90 if (!super::init(inOwner, (IOEventSource::Action) inAction) )
91 return false;
92
93 setTimeoutFunc();
94 if (!calloutEntry)
95 return false;
96
97 return true;
98}
99
100IOTimerEventSource *
101IOTimerEventSource::timerEventSource(OSObject *inOwner, Action inAction)
102{
103 IOTimerEventSource *me = new IOTimerEventSource;
104
105 if (me && !me->init(inOwner, inAction)) {
106 me->free();
107 return 0;
108 }
109
110 return me;
111}
112
113void IOTimerEventSource::free()
114{
115 if (calloutEntry) {
116 cancelTimeout();
117 thread_call_free((thread_call_t) calloutEntry);
118 }
119
120 super::free();
121}
122
123void IOTimerEventSource::cancelTimeout()
124{
125 thread_call_cancel((thread_call_t) calloutEntry);
126 AbsoluteTime_to_scalar(&abstime) = 0;
127}
128
129void IOTimerEventSource::enable()
130{
131 super::enable();
132 if (kIOReturnSuccess != wakeAtTime(abstime))
133 super::disable(); // Problem re-scheduling timeout ignore enable
134}
135
136void IOTimerEventSource::disable()
137{
138 thread_call_cancel((thread_call_t) calloutEntry);
139 super::disable();
140}
141
142IOReturn IOTimerEventSource::setTimeoutTicks(UInt32 ticks)
143{
144 return setTimeout(ticks, NSEC_PER_SEC/hz);
145}
146
147IOReturn IOTimerEventSource::setTimeoutMS(UInt32 ms)
148{
149 return setTimeout(ms, kMillisecondScale);
150}
151
152IOReturn IOTimerEventSource::setTimeoutUS(UInt32 us)
153{
154 return setTimeout(us, kMicrosecondScale);
155}
156
157IOReturn IOTimerEventSource::setTimeout(UInt32 interval, UInt32 scale_factor)
158{
159 AbsoluteTime end;
160
161 clock_interval_to_deadline(interval, scale_factor, &end);
162 return wakeAtTime(end);
163}
164
165IOReturn IOTimerEventSource::setTimeout(mach_timespec_t interval)
166{
167 AbsoluteTime end, nsecs;
168
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);
174
175 return wakeAtTime(end);
176}
177
178IOReturn IOTimerEventSource::setTimeout(AbsoluteTime interval)
179{
180 AbsoluteTime end;
181
182 clock_get_uptime(&end);
183 ADD_ABSOLUTETIME(&end, &interval);
184
185 return wakeAtTime(end);
186}
187
188IOReturn IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks)
189{
190 return wakeAtTime(ticks, NSEC_PER_SEC/hz);
191}
192
193IOReturn IOTimerEventSource::wakeAtTimeMS(UInt32 ms)
194{
195 return wakeAtTime(ms, kMillisecondScale);
196}
197
198IOReturn IOTimerEventSource::wakeAtTimeUS(UInt32 us)
199{
200 return wakeAtTime(us, kMicrosecondScale);
201}
202
203IOReturn IOTimerEventSource::wakeAtTime(UInt32 abstime, UInt32 scale_factor)
204{
205 AbsoluteTime end;
206 clock_interval_to_absolutetime_interval(abstime, scale_factor, &end);
207
208 return wakeAtTime(end);
209}
210
211IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t abstime)
212{
213 AbsoluteTime end, nsecs;
214
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);
220
221 return wakeAtTime(end);
222}
223
224IOReturn IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime)
225{
226 if (!action)
227 return kIOReturnNoResources;
228
229 abstime = inAbstime;
230 if ( enabled && AbsoluteTime_to_scalar(&abstime) )
231 thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
232
233 return kIOReturnSuccess;
234}