Deleted Added
full compact
kern_timeout.c (69147) kern_timeout.c (72200)
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
1/*-
2 * Copyright (c) 1982, 1986, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 22 unchanged lines hidden (view full) ---

31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * From: @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
39 * $FreeBSD: head/sys/kern/kern_timeout.c 69147 2000-11-25 06:22:16Z jlemon $
39 * $FreeBSD: head/sys/kern/kern_timeout.c 72200 2001-02-09 06:11:45Z bmilekic $
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/callout.h>
45#include <sys/kernel.h>
46#include <sys/mutex.h>
47

--- 38 unchanged lines hidden (view full) ---

86 register int steps; /* #steps since we last allowed interrupts */
87
88#ifndef MAX_SOFTCLOCK_STEPS
89#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */
90#endif /* MAX_SOFTCLOCK_STEPS */
91
92 steps = 0;
93 s = splhigh();
40 */
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/callout.h>
45#include <sys/kernel.h>
46#include <sys/mutex.h>
47

--- 38 unchanged lines hidden (view full) ---

86 register int steps; /* #steps since we last allowed interrupts */
87
88#ifndef MAX_SOFTCLOCK_STEPS
89#define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */
90#endif /* MAX_SOFTCLOCK_STEPS */
91
92 steps = 0;
93 s = splhigh();
94 mtx_enter(&callout_lock, MTX_SPIN);
94 mtx_lock_spin(&callout_lock);
95 while (softticks != ticks) {
96 softticks++;
97 /*
98 * softticks may be modified by hard clock, so cache
99 * it while we work on a given bucket.
100 */
101 curticks = softticks;
102 bucket = &callwheel[curticks & callwheelmask];
103 c = TAILQ_FIRST(bucket);
104 while (c) {
105 if (c->c_time != curticks) {
106 c = TAILQ_NEXT(c, c_links.tqe);
107 ++steps;
108 if (steps >= MAX_SOFTCLOCK_STEPS) {
109 nextsoftcheck = c;
110 /* Give interrupts a chance. */
95 while (softticks != ticks) {
96 softticks++;
97 /*
98 * softticks may be modified by hard clock, so cache
99 * it while we work on a given bucket.
100 */
101 curticks = softticks;
102 bucket = &callwheel[curticks & callwheelmask];
103 c = TAILQ_FIRST(bucket);
104 while (c) {
105 if (c->c_time != curticks) {
106 c = TAILQ_NEXT(c, c_links.tqe);
107 ++steps;
108 if (steps >= MAX_SOFTCLOCK_STEPS) {
109 nextsoftcheck = c;
110 /* Give interrupts a chance. */
111 mtx_exit(&callout_lock, MTX_SPIN);
111 mtx_unlock_spin(&callout_lock);
112 splx(s);
113 s = splhigh();
112 splx(s);
113 s = splhigh();
114 mtx_enter(&callout_lock, MTX_SPIN);
114 mtx_lock_spin(&callout_lock);
115 c = nextsoftcheck;
116 steps = 0;
117 }
118 } else {
119 void (*c_func)(void *);
120 void *c_arg;
121 int c_flags;
122

--- 6 unchanged lines hidden (view full) ---

129 if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
130 c->c_flags = CALLOUT_LOCAL_ALLOC;
131 SLIST_INSERT_HEAD(&callfree, c,
132 c_links.sle);
133 } else {
134 c->c_flags =
135 (c->c_flags & ~CALLOUT_PENDING);
136 }
115 c = nextsoftcheck;
116 steps = 0;
117 }
118 } else {
119 void (*c_func)(void *);
120 void *c_arg;
121 int c_flags;
122

--- 6 unchanged lines hidden (view full) ---

129 if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
130 c->c_flags = CALLOUT_LOCAL_ALLOC;
131 SLIST_INSERT_HEAD(&callfree, c,
132 c_links.sle);
133 } else {
134 c->c_flags =
135 (c->c_flags & ~CALLOUT_PENDING);
136 }
137 mtx_exit(&callout_lock, MTX_SPIN);
137 mtx_unlock_spin(&callout_lock);
138 if (!(c_flags & CALLOUT_MPSAFE))
138 if (!(c_flags & CALLOUT_MPSAFE))
139 mtx_enter(&Giant, MTX_DEF);
139 mtx_lock(&Giant);
140 splx(s);
141 c_func(c_arg);
142 s = splhigh();
143 if (!(c_flags & CALLOUT_MPSAFE))
140 splx(s);
141 c_func(c_arg);
142 s = splhigh();
143 if (!(c_flags & CALLOUT_MPSAFE))
144 mtx_exit(&Giant, MTX_DEF);
145 mtx_enter(&callout_lock, MTX_SPIN);
144 mtx_unlock(&Giant);
145 mtx_lock_spin(&callout_lock);
146 steps = 0;
147 c = nextsoftcheck;
148 }
149 }
150 }
151 nextsoftcheck = NULL;
146 steps = 0;
147 c = nextsoftcheck;
148 }
149 }
150 }
151 nextsoftcheck = NULL;
152 mtx_exit(&callout_lock, MTX_SPIN);
152 mtx_unlock_spin(&callout_lock);
153 splx(s);
154}
155
156/*
157 * timeout --
158 * Execute a function after a specified length of time.
159 *
160 * untimeout --

--- 14 unchanged lines hidden (view full) ---

175 void *arg;
176 int to_ticks;
177{
178 int s;
179 struct callout *new;
180 struct callout_handle handle;
181
182 s = splhigh();
153 splx(s);
154}
155
156/*
157 * timeout --
158 * Execute a function after a specified length of time.
159 *
160 * untimeout --

--- 14 unchanged lines hidden (view full) ---

175 void *arg;
176 int to_ticks;
177{
178 int s;
179 struct callout *new;
180 struct callout_handle handle;
181
182 s = splhigh();
183 mtx_enter(&callout_lock, MTX_SPIN);
183 mtx_lock_spin(&callout_lock);
184
185 /* Fill in the next free callout structure. */
186 new = SLIST_FIRST(&callfree);
187 if (new == NULL)
188 /* XXX Attempt to malloc first */
189 panic("timeout table full");
190 SLIST_REMOVE_HEAD(&callfree, c_links.sle);
191
192 callout_reset(new, to_ticks, ftn, arg);
193
194 handle.callout = new;
184
185 /* Fill in the next free callout structure. */
186 new = SLIST_FIRST(&callfree);
187 if (new == NULL)
188 /* XXX Attempt to malloc first */
189 panic("timeout table full");
190 SLIST_REMOVE_HEAD(&callfree, c_links.sle);
191
192 callout_reset(new, to_ticks, ftn, arg);
193
194 handle.callout = new;
195 mtx_exit(&callout_lock, MTX_SPIN);
195 mtx_unlock_spin(&callout_lock);
196 splx(s);
197 return (handle);
198}
199
200void
201untimeout(ftn, arg, handle)
202 timeout_t *ftn;
203 void *arg;

--- 5 unchanged lines hidden (view full) ---

209 * Check for a handle that was initialized
210 * by callout_handle_init, but never used
211 * for a real timeout.
212 */
213 if (handle.callout == NULL)
214 return;
215
216 s = splhigh();
196 splx(s);
197 return (handle);
198}
199
200void
201untimeout(ftn, arg, handle)
202 timeout_t *ftn;
203 void *arg;

--- 5 unchanged lines hidden (view full) ---

209 * Check for a handle that was initialized
210 * by callout_handle_init, but never used
211 * for a real timeout.
212 */
213 if (handle.callout == NULL)
214 return;
215
216 s = splhigh();
217 mtx_enter(&callout_lock, MTX_SPIN);
217 mtx_lock_spin(&callout_lock);
218 if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
219 callout_stop(handle.callout);
218 if (handle.callout->c_func == ftn && handle.callout->c_arg == arg)
219 callout_stop(handle.callout);
220 mtx_exit(&callout_lock, MTX_SPIN);
220 mtx_unlock_spin(&callout_lock);
221 splx(s);
222}
223
224void
225callout_handle_init(struct callout_handle *handle)
226{
227 handle->callout = NULL;
228}

--- 17 unchanged lines hidden (view full) ---

246 struct callout *c;
247 int to_ticks;
248 void (*ftn) __P((void *));
249 void *arg;
250{
251 int s;
252
253 s = splhigh();
221 splx(s);
222}
223
224void
225callout_handle_init(struct callout_handle *handle)
226{
227 handle->callout = NULL;
228}

--- 17 unchanged lines hidden (view full) ---

246 struct callout *c;
247 int to_ticks;
248 void (*ftn) __P((void *));
249 void *arg;
250{
251 int s;
252
253 s = splhigh();
254 mtx_enter(&callout_lock, MTX_SPIN);
254 mtx_lock_spin(&callout_lock);
255 if (c->c_flags & CALLOUT_PENDING)
256 callout_stop(c);
257
258 /*
259 * We could spl down here and back up at the TAILQ_INSERT_TAIL,
260 * but there's no point since doing this setup doesn't take much
261 * time.
262 */
263 if (to_ticks <= 0)
264 to_ticks = 1;
265
266 c->c_arg = arg;
267 c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
268 c->c_func = ftn;
269 c->c_time = ticks + to_ticks;
270 TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask],
271 c, c_links.tqe);
255 if (c->c_flags & CALLOUT_PENDING)
256 callout_stop(c);
257
258 /*
259 * We could spl down here and back up at the TAILQ_INSERT_TAIL,
260 * but there's no point since doing this setup doesn't take much
261 * time.
262 */
263 if (to_ticks <= 0)
264 to_ticks = 1;
265
266 c->c_arg = arg;
267 c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
268 c->c_func = ftn;
269 c->c_time = ticks + to_ticks;
270 TAILQ_INSERT_TAIL(&callwheel[c->c_time & callwheelmask],
271 c, c_links.tqe);
272 mtx_exit(&callout_lock, MTX_SPIN);
272 mtx_unlock_spin(&callout_lock);
273 splx(s);
274}
275
276void
277callout_stop(c)
278 struct callout *c;
279{
280 int s;
281
282 s = splhigh();
273 splx(s);
274}
275
276void
277callout_stop(c)
278 struct callout *c;
279{
280 int s;
281
282 s = splhigh();
283 mtx_enter(&callout_lock, MTX_SPIN);
283 mtx_lock_spin(&callout_lock);
284 /*
285 * Don't attempt to delete a callout that's not on the queue.
286 */
287 if (!(c->c_flags & CALLOUT_PENDING)) {
288 c->c_flags &= ~CALLOUT_ACTIVE;
284 /*
285 * Don't attempt to delete a callout that's not on the queue.
286 */
287 if (!(c->c_flags & CALLOUT_PENDING)) {
288 c->c_flags &= ~CALLOUT_ACTIVE;
289 mtx_exit(&callout_lock, MTX_SPIN);
289 mtx_unlock_spin(&callout_lock);
290 splx(s);
291 return;
292 }
293 c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
294
295 if (nextsoftcheck == c) {
296 nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
297 }
298 TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_links.tqe);
299 c->c_func = NULL;
300
301 if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
302 SLIST_INSERT_HEAD(&callfree, c, c_links.sle);
303 }
290 splx(s);
291 return;
292 }
293 c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
294
295 if (nextsoftcheck == c) {
296 nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
297 }
298 TAILQ_REMOVE(&callwheel[c->c_time & callwheelmask], c, c_links.tqe);
299 c->c_func = NULL;
300
301 if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
302 SLIST_INSERT_HEAD(&callfree, c, c_links.sle);
303 }
304 mtx_exit(&callout_lock, MTX_SPIN);
304 mtx_unlock_spin(&callout_lock);
305 splx(s);
306}
307
308void
309callout_init(c, mpsafe)
310 struct callout *c;
311 int mpsafe;
312{

--- 48 unchanged lines hidden (view full) ---

361
362 /*
363 * Now rip through the timer calltodo list looking for timers
364 * to expire.
365 */
366
367 /* don't collide with softclock() */
368 s = splhigh();
305 splx(s);
306}
307
308void
309callout_init(c, mpsafe)
310 struct callout *c;
311 int mpsafe;
312{

--- 48 unchanged lines hidden (view full) ---

361
362 /*
363 * Now rip through the timer calltodo list looking for timers
364 * to expire.
365 */
366
367 /* don't collide with softclock() */
368 s = splhigh();
369 mtx_enter(&callout_lock, MTX_SPIN);
369 mtx_lock_spin(&callout_lock);
370 for (p = calltodo.c_next; p != NULL; p = p->c_next) {
371 p->c_time -= delta_ticks;
372
373 /* Break if the timer had more time on it than delta_ticks */
374 if (p->c_time > 0)
375 break;
376
377 /* take back the ticks the timer didn't use (p->c_time <= 0) */
378 delta_ticks = -p->c_time;
379 }
370 for (p = calltodo.c_next; p != NULL; p = p->c_next) {
371 p->c_time -= delta_ticks;
372
373 /* Break if the timer had more time on it than delta_ticks */
374 if (p->c_time > 0)
375 break;
376
377 /* take back the ticks the timer didn't use (p->c_time <= 0) */
378 delta_ticks = -p->c_time;
379 }
380 mtx_exit(&callout_lock, MTX_SPIN);
380 mtx_unlock_spin(&callout_lock);
381 splx(s);
382
383 return;
384}
385#endif /* APM_FIXUP_CALLTODO */
381 splx(s);
382
383 return;
384}
385#endif /* APM_FIXUP_CALLTODO */