2 * Copyright (c) 1993-1995, 1999-2004 Apple Computer, Inc.
5 * @APPLE_LICENSE_HEADER_START@
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
22 * @APPLE_LICENSE_HEADER_END@
25 * Timer interrupt callout module.
29 * 20 December 2000 (debo)
33 #include <mach/mach_types.h>
35 #include <kern/clock.h>
36 #include <kern/processor.h>
38 #include <kern/timer_call.h>
39 #include <kern/call_entry.h>
41 decl_simple_lock_data(static,timer_call_lock
)
52 #define qe(x) ((queue_entry_t)(x))
53 #define TC(x) ((timer_call_t)(x))
56 timer_call_initialize(void)
60 simple_lock_init(&timer_call_lock
, 0);
63 simple_lock(&timer_call_lock
);
65 clock_set_timer_func((clock_timer_func_t
)timer_call_interrupt
);
67 simple_unlock(&timer_call_lock
);
74 timer_call_func_t func
,
75 timer_call_param_t param0
)
77 call_entry_setup(call
, func
, param0
);
82 _delayed_call_enqueue(
88 current
= TC(queue_first(queue
));
91 if ( queue_end(queue
, qe(current
)) ||
92 call
->deadline
< current
->deadline
) {
93 current
= TC(queue_prev(qe(current
)));
97 current
= TC(queue_next(qe(current
)));
100 insque(qe(call
), qe(current
));
101 if (++timer_call_vars
.delayed_num
> timer_call_vars
.delayed_hiwat
)
102 timer_call_vars
.delayed_hiwat
= timer_call_vars
.delayed_num
;
104 call
->state
= DELAYED
;
109 _delayed_call_dequeue(
112 (void)remque(qe(call
));
113 timer_call_vars
.delayed_num
--;
120 _set_delayed_call_timer(
123 clock_set_timer_deadline(call
->deadline
);
131 boolean_t result
= TRUE
;
136 simple_lock(&timer_call_lock
);
138 if (call
->state
== DELAYED
)
139 _delayed_call_dequeue(call
);
144 call
->deadline
= deadline
;
146 queue
= &PROCESSOR_DATA(current_processor(), timer_call_queue
);
148 _delayed_call_enqueue(queue
, call
);
150 if (queue_first(queue
) == qe(call
))
151 _set_delayed_call_timer(call
);
153 simple_unlock(&timer_call_lock
);
162 timer_call_param_t param1
,
165 boolean_t result
= TRUE
;
170 simple_lock(&timer_call_lock
);
172 if (call
->state
== DELAYED
)
173 _delayed_call_dequeue(call
);
177 call
->param1
= param1
;
178 call
->deadline
= deadline
;
180 queue
= &PROCESSOR_DATA(current_processor(), timer_call_queue
);
182 _delayed_call_enqueue(queue
, call
);
184 if (queue_first(queue
) == qe(call
))
185 _set_delayed_call_timer(call
);
187 simple_unlock(&timer_call_lock
);
197 boolean_t result
= TRUE
;
201 simple_lock(&timer_call_lock
);
203 if (call
->state
== DELAYED
)
204 _delayed_call_dequeue(call
);
208 simple_unlock(&timer_call_lock
);
215 timer_call_is_delayed(
219 boolean_t result
= FALSE
;
223 simple_lock(&timer_call_lock
);
225 if (call
->state
== DELAYED
) {
226 if (deadline
!= NULL
)
227 *deadline
= call
->deadline
;
231 simple_unlock(&timer_call_lock
);
238 * Called at splclock.
243 processor_t processor
)
246 queue_t queue
, myqueue
;
248 assert(processor
!= current_processor());
250 queue
= &PROCESSOR_DATA(processor
, timer_call_queue
);
251 myqueue
= &PROCESSOR_DATA(current_processor(), timer_call_queue
);
253 simple_lock(&timer_call_lock
);
255 call
= TC(queue_first(queue
));
257 while (!queue_end(queue
, qe(call
))) {
258 _delayed_call_dequeue(call
);
260 _delayed_call_enqueue(myqueue
, call
);
262 call
= TC(queue_first(queue
));
265 call
= TC(queue_first(myqueue
));
267 if (!queue_end(myqueue
, qe(call
)))
268 _set_delayed_call_timer(call
);
270 simple_unlock(&timer_call_lock
);
275 timer_call_interrupt(
281 simple_lock(&timer_call_lock
);
283 queue
= &PROCESSOR_DATA(current_processor(), timer_call_queue
);
285 call
= TC(queue_first(queue
));
287 while (!queue_end(queue
, qe(call
))) {
288 if (call
->deadline
<= timestamp
) {
289 timer_call_func_t func
;
290 timer_call_param_t param0
, param1
;
292 _delayed_call_dequeue(call
);
295 param0
= call
->param0
;
296 param1
= call
->param1
;
298 simple_unlock(&timer_call_lock
);
300 (*func
)(param0
, param1
);
302 simple_lock(&timer_call_lock
);
307 call
= TC(queue_first(queue
));
310 if (!queue_end(queue
, qe(call
)))
311 _set_delayed_call_timer(call
);
313 simple_unlock(&timer_call_lock
);