]>
git.saurik.com Git - apple/network_cmds.git/blob - rtadvd.tproj/timer.c
1 /* $KAME: timer.c,v 1.4 2000/05/27 11:30:43 jinmei Exp $ */
4 * Copyright (C) 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * $FreeBSD: src/usr.sbin/rtadvd/timer.c,v 1.1.2.2 2001/07/03 11:02:14 ume Exp $
40 #if defined(__NetBSD__) || defined(__OpenBSD__)
45 static struct rtadvd_timer timer_head
;
47 #define MILLION 1000000
48 #define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\
49 (t1)->tv_usec == (t2)->tv_usec)
51 static struct timeval tm_max
= {0x7fffffff, 0x7fffffff};
56 memset(&timer_head
, 0, sizeof(timer_head
));
58 timer_head
.next
= timer_head
.prev
= &timer_head
;
59 timer_head
.tm
= tm_max
;
63 rtadvd_add_timer(void (*timeout
) __P((void *)),
64 void (*update
) __P((void *, struct timeval
*)),
65 void *timeodata
, void *updatedata
)
67 struct rtadvd_timer
*newtimer
;
69 if ((newtimer
= malloc(sizeof(*newtimer
))) == NULL
) {
71 "<%s> can't allocate memory", __FUNCTION__
);
75 memset(newtimer
, 0, sizeof(*newtimer
));
77 if (timeout
== NULL
) {
79 "<%s> timeout function unspecfied", __FUNCTION__
);
84 "<%s> update function unspecfied", __FUNCTION__
);
87 newtimer
->expire
= timeout
;
88 newtimer
->update
= update
;
89 newtimer
->expire_data
= timeodata
;
90 newtimer
->update_data
= updatedata
;
91 newtimer
->tm
= tm_max
;
94 insque(newtimer
, &timer_head
);
100 rtadvd_remove_timer(struct rtadvd_timer
**timer
)
108 rtadvd_set_timer(struct timeval
*tm
, struct rtadvd_timer
*timer
)
112 /* reset the timer */
113 gettimeofday(&now
, NULL
);
115 TIMEVAL_ADD(&now
, tm
, &timer
->tm
);
117 /* update the next expiration time */
118 if (TIMEVAL_LT(timer
->tm
, timer_head
.tm
))
119 timer_head
.tm
= timer
->tm
;
125 * Check expiration for each timer. If a timer is expired,
126 * call the expire function for the timer and update the timer.
127 * Return the next interval for select() call.
132 static struct timeval returnval
;
134 struct rtadvd_timer
*tm
= timer_head
.next
;
136 gettimeofday(&now
, NULL
);
138 timer_head
.tm
= tm_max
;
140 while(tm
!= &timer_head
) {
141 if (TIMEVAL_LEQ(tm
->tm
, now
)) {
142 (*tm
->expire
)(tm
->expire_data
);
143 (*tm
->update
)(tm
->update_data
, &tm
->tm
);
144 TIMEVAL_ADD(&tm
->tm
, &now
, &tm
->tm
);
147 if (TIMEVAL_LT(tm
->tm
, timer_head
.tm
))
148 timer_head
.tm
= tm
->tm
;
153 if (TIMEVAL_EQUAL(&tm_max
, &timer_head
.tm
)) {
154 /* no need to timeout */
157 else if (TIMEVAL_LT(timer_head
.tm
, now
)) {
158 /* this may occur when the interval is too small */
159 returnval
.tv_sec
= returnval
.tv_usec
= 0;
162 TIMEVAL_SUB(&timer_head
.tm
, &now
, &returnval
);
167 rtadvd_timer_rest(struct rtadvd_timer
*timer
)
169 static struct timeval returnval
, now
;
171 gettimeofday(&now
, NULL
);
172 if (TIMEVAL_LEQ(timer
->tm
, now
)) {
174 "<%s> a timer must be expired, but not yet",
176 returnval
.tv_sec
= returnval
.tv_usec
= 0;
179 TIMEVAL_SUB(&timer
->tm
, &now
, &returnval
);
186 TIMEVAL_ADD(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
190 if ((l
= a
->tv_usec
+ b
->tv_usec
) < MILLION
) {
192 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
;
195 result
->tv_usec
= l
- MILLION
;
196 result
->tv_sec
= a
->tv_sec
+ b
->tv_sec
+ 1;
202 * XXX: this function assumes that a >= b.
205 TIMEVAL_SUB(struct timeval
*a
, struct timeval
*b
, struct timeval
*result
)
209 if ((l
= a
->tv_usec
- b
->tv_usec
) >= 0) {
211 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
;
214 result
->tv_usec
= MILLION
+ l
;
215 result
->tv_sec
= a
->tv_sec
- b
->tv_sec
- 1;