|
|
1.1 root 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
50: OSDefineMetaClassAndStructors( IOTimerEventSource, IOEventSource )
51:
52: bool IOTimerEventSource::checkForWork() { return false; }
53:
54: // Timeout handler function. This function is called by the kernel when
55: // the timeout interval expires.
56: //
57: void IOTimerEventSource::timeout(void *self)
58: {
59: IOTimerEventSource *me = (IOTimerEventSource *) self;
60:
61: if (me->enabled) {
62: Action doit = (Action) me->action;
63:
64: if (doit) {
65: IOWorkLoop *loop = me->workLoop;
66:
67: IOTimeStampConstant(IODBG_TIMES(IOTIMES_ACTION),
68: (unsigned int) doit, (unsigned int) me->owner);
69: loop->closeGate();
70: (*doit)(me->owner, me);
71: loop->openGate();
72: }
73: }
74: }
75:
76: void IOTimerEventSource::setTimeoutFunc()
77: {
78: calloutEntry = (void *) thread_call_allocate((thread_call_func_t) timeout,
79: (thread_call_param_t) this);
80: }
81:
82: bool IOTimerEventSource::init(OSObject *inOwner, Action inAction)
83: {
84: if (!super::init(inOwner, (IOEventSource::Action) inAction) )
85: return false;
86:
87: setTimeoutFunc();
88: if (!calloutEntry)
89: return false;
90:
91: return true;
92: }
93:
94: IOTimerEventSource *
95: IOTimerEventSource::timerEventSource(OSObject *inOwner, Action inAction)
96: {
97: IOTimerEventSource *me = new IOTimerEventSource;
98:
99: if (me && !me->init(inOwner, inAction)) {
100: me->free();
101: return 0;
102: }
103:
104: return me;
105: }
106:
107: void IOTimerEventSource::free()
108: {
109: if (calloutEntry) {
110: cancelTimeout();
111: thread_call_free((thread_call_t) calloutEntry);
112: }
113:
114: super::free();
115: }
116:
117: void IOTimerEventSource::cancelTimeout()
118: {
119: thread_call_cancel((thread_call_t) calloutEntry);
120: AbsoluteTime_to_scalar(&abstime) = 0;
121: }
122:
123: void IOTimerEventSource::enable()
124: {
125: super::enable();
126: if (kIOReturnSuccess != wakeAtTime(abstime))
127: super::disable(); // Problem re-scheduling timeout ignore enable
128: }
129:
130: void IOTimerEventSource::disable()
131: {
132: thread_call_cancel((thread_call_t) calloutEntry);
133: super::disable();
134: }
135:
136: IOReturn IOTimerEventSource::setTimeoutTicks(UInt32 ticks)
137: {
138: return setTimeout(ticks, NSEC_PER_SEC/hz);
139: }
140:
141: IOReturn IOTimerEventSource::setTimeoutMS(UInt32 ms)
142: {
143: return setTimeout(ms, kMillisecondScale);
144: }
145:
146: IOReturn IOTimerEventSource::setTimeoutUS(UInt32 us)
147: {
148: return setTimeout(us, kMicrosecondScale);
149: }
150:
151: IOReturn IOTimerEventSource::setTimeout(UInt32 interval, UInt32 scale_factor)
152: {
153: AbsoluteTime end;
154:
155: clock_interval_to_deadline(interval, scale_factor, &end);
156: return wakeAtTime(end);
157: }
158:
159: IOReturn IOTimerEventSource::setTimeout(mach_timespec_t interval)
160: {
161: AbsoluteTime end, nsecs;
162:
163: clock_interval_to_absolutetime_interval
164: (interval.tv_nsec, kNanosecondScale, &nsecs);
165: clock_interval_to_deadline
166: (interval.tv_sec, NSEC_PER_SEC, &end);
167: ADD_ABSOLUTETIME(&end, &nsecs);
168:
169: return wakeAtTime(end);
170: }
171:
172: IOReturn IOTimerEventSource::setTimeout(AbsoluteTime interval)
173: {
174: AbsoluteTime end;
175:
176: clock_get_uptime(&end);
177: ADD_ABSOLUTETIME(&end, &interval);
178:
179: return wakeAtTime(end);
180: }
181:
182: IOReturn IOTimerEventSource::wakeAtTimeTicks(UInt32 ticks)
183: {
184: return wakeAtTime(ticks, NSEC_PER_SEC/hz);
185: }
186:
187: IOReturn IOTimerEventSource::wakeAtTimeMS(UInt32 ms)
188: {
189: return wakeAtTime(ms, kMillisecondScale);
190: }
191:
192: IOReturn IOTimerEventSource::wakeAtTimeUS(UInt32 us)
193: {
194: return wakeAtTime(us, kMicrosecondScale);
195: }
196:
197: IOReturn IOTimerEventSource::wakeAtTime(UInt32 abstime, UInt32 scale_factor)
198: {
199: AbsoluteTime end;
200: clock_interval_to_absolutetime_interval(abstime, scale_factor, &end);
201:
202: return wakeAtTime(end);
203: }
204:
205: IOReturn IOTimerEventSource::wakeAtTime(mach_timespec_t abstime)
206: {
207: AbsoluteTime end, nsecs;
208:
209: clock_interval_to_absolutetime_interval
210: (abstime.tv_nsec, kNanosecondScale, &nsecs);
211: clock_interval_to_absolutetime_interval
212: (abstime.tv_sec, kSecondScale, &end);
213: ADD_ABSOLUTETIME(&end, &nsecs);
214:
215: return wakeAtTime(end);
216: }
217:
218: IOReturn IOTimerEventSource::wakeAtTime(AbsoluteTime inAbstime)
219: {
220: if (!action)
221: return kIOReturnNoResources;
222:
223: abstime = inAbstime;
224: if ( enabled && AbsoluteTime_to_scalar(&abstime) )
225: thread_call_enter_delayed((thread_call_t) calloutEntry, abstime);
226:
227: return kIOReturnSuccess;
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.