1 /* $NetBSD: schedule.c,v 1.6 2009/01/23 08:25:07 tteras Exp $ */
3 /* $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $ */
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Copyright (C) 2008 Timo Teras.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the project nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 #include <sys/types.h>
38 #include <sys/param.h>
40 #include <sys/queue.h>
41 #include <sys/socket.h>
57 #define TAILQ_FOREACH(elm, head, field) \
58 for (elm = TAILQ_FIRST(head); elm; elm = TAILQ_NEXT(elm, field))
61 static TAILQ_HEAD(_schedtree
, sched
) sctree
;
64 sched_get_monotonic_time(tv
)
67 #ifdef HAVE_CLOCK_MONOTONIC
70 clock_gettime(CLOCK_MONOTONIC
, &ts
);
71 tv
->tv_sec
= ts
.tv_sec
;
72 tv
->tv_usec
= ts
.tv_nsec
/ 1000;
74 gettimeofday(tv
, NULL
);
79 sched_monotonic_to_time_t(tv
, now
)
80 struct timeval
*tv
, *now
;
82 #ifdef HAVE_CLOCK_MONOTONIC
83 struct timeval mynow
, res
;
86 sched_get_monotonic_time(&mynow
);
89 timersub(now
, tv
, &res
);
91 return time(NULL
) + res
.tv_sec
;
100 * time to block until next event.
101 * if no entry, NULL returned.
106 static struct timeval timeout
;
110 sched_get_monotonic_time(&now
);
111 while (!TAILQ_EMPTY(&sctree
) &&
112 timercmp(&TAILQ_FIRST(&sctree
)->xtime
, &now
, <=)) {
113 void (*func
)(struct sched
*);
115 p
= TAILQ_FIRST(&sctree
);
121 p
= TAILQ_FIRST(&sctree
);
125 timersub(&p
->xtime
, &now
, &timeout
);
131 * add new schedule to schedule table.
134 sched_schedule(sc
, tick
, func
)
137 void (*func
) __P((struct sched
*));
147 sc
->tick
.tv_sec
= tick
;
148 sc
->tick
.tv_usec
= 0;
149 sched_get_monotonic_time(&now
);
150 timeradd(&now
, &sc
->tick
, &sc
->xtime
);
152 /* add to schedule table */
153 TAILQ_FOREACH(p
, &sctree
, chain
) {
154 if (timercmp(&sc
->xtime
, &p
->xtime
, <))
158 TAILQ_INSERT_TAIL(&sctree
, sc
, chain
);
160 TAILQ_INSERT_BEFORE(p
, sc
, chain
);
164 * cancel scheduled callback
170 if (sc
->func
!= NULL
) {
171 TAILQ_REMOVE(&sctree
, sc
, chain
);
186 struct scheddump
*dst
;
187 struct timeval now
, created
;
194 TAILQ_FOREACH(p
, &sctree
, chain
)
201 *len
= cnt
* sizeof(*dst
);
203 new = racoon_malloc(*len
);
206 dst
= (struct scheddump
*)new;
208 sched_get_monotonic_time(&now
);
209 p
= TAILQ_FIRST(&sctree
);
211 timersub(&p
->xtime
, &p
->tick
, &created
);
212 dst
->xtime
= p
->xtime
.tv_sec
;
214 dst
->created
= sched_monotonic_to_time_t(&created
, &now
);
215 dst
->tick
= p
->tick
.tv_sec
;
217 p
= TAILQ_NEXT(p
, chain
);
228 /* initialize schedule table */
236 #include <sys/types.h>
237 #include <sys/time.h>
245 printf("execute %d\n", *tick
);
255 read(0, buf
, sizeof(buf
));
257 struct scheddump
*scbuf
, *p
;
259 sched_dump((caddr_t
*)&scbuf
, &len
);
262 for (p
= scbuf
; len
; p
++) {
263 printf("xtime=%ld\n", p
->xtime
);
270 tick
= (int *)racoon_malloc(sizeof(*tick
));
272 printf("new queue tick = %d\n", *tick
);
273 sched_new(*tick
, test
, tick
);
282 struct timeval
*timeout
;
295 timeout
= schedular();
297 error
= select(nfds
, &rfds
, (fd_set
*)0, (fd_set
*)0, timeout
);
300 case EINTR
: continue;
307 if (FD_ISSET(0, &rfds
))