]>
Commit | Line | Data |
---|---|---|
d1e348cf A |
1 | /* $NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ |
2 | ||
52b7d2ce A |
3 | /* $KAME: schedule.c,v 1.19 2001/11/05 10:53:19 sakane Exp $ */ |
4 | ||
5 | /* | |
6 | * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. | |
7 | * All rights reserved. | |
8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | |
15 | * notice, this list of conditions and the following disclaimer in the | |
16 | * documentation and/or other materials provided with the distribution. | |
17 | * 3. Neither the name of the project nor the names of its contributors | |
18 | * may be used to endorse or promote products derived from this software | |
19 | * without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND | |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE | |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
31 | * SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | #include "config.h" | |
35 | ||
36 | #include <sys/types.h> | |
37 | #include <sys/param.h> | |
38 | #include <sys/time.h> | |
39 | #include <sys/queue.h> | |
40 | #include <sys/socket.h> | |
41 | ||
42 | #include <stdlib.h> | |
43 | #include <stdio.h> | |
44 | #include <string.h> | |
45 | #include <errno.h> | |
46 | #include <time.h> | |
65c25746 | 47 | #include <dispatch/dispatch.h> |
52b7d2ce A |
48 | |
49 | #include "misc.h" | |
50 | #include "plog.h" | |
51 | #include "schedule.h" | |
52 | #include "var.h" | |
53 | #include "gcmalloc.h" | |
e8d9021d | 54 | #include "power_mgmt.h" |
65c25746 | 55 | #include "localconf.h" |
52b7d2ce | 56 | |
93762ec7 A |
57 | #if !defined(__LP64__) |
58 | // year 2038 problem and fix for 32-bit only | |
52b7d2ce | 59 | #define FIXY2038PROBLEM |
93762ec7 | 60 | #endif |
52b7d2ce | 61 | |
52b7d2ce | 62 | |
d1e348cf | 63 | extern int terminated; |
52b7d2ce A |
64 | |
65 | #ifdef FIXY2038PROBLEM | |
66 | #define Y2038TIME_T 0x7fffffff | |
67 | static time_t launched; /* time when the program launched. */ | |
68 | static time_t deltaY2038; | |
69 | #endif | |
70 | ||
71 | static TAILQ_HEAD(_schedtree, sched) sctree; | |
72 | ||
52b7d2ce | 73 | |
65c25746 A |
74 | void |
75 | timer_handler(struct sched *sched) | |
52b7d2ce | 76 | { |
65c25746 A |
77 | if (slept_at || woke_at) |
78 | sched->dead = 1; | |
79 | ||
80 | TAILQ_REMOVE(&sctree, sched, chain); | |
81 | ||
82 | if (!sched->dead) { | |
83 | if (sched->func != NULL && !terminated) { | |
84 | (sched->func)(sched->param); | |
85 | } | |
86 | } | |
87 | racoon_free(sched); | |
52b7d2ce A |
88 | } |
89 | ||
90 | /* | |
91 | * add new schedule to schedule table. | |
92 | */ | |
65c25746 A |
93 | schedule_ref |
94 | sched_new(time_t tick, void (*func) (void *), void *param) | |
52b7d2ce | 95 | { |
65c25746 A |
96 | static schedule_ref next_ref = 1; |
97 | struct sched *new_sched; | |
98 | ||
99 | if (next_ref == 0) | |
100 | next_ref++; | |
101 | ||
102 | new_sched = (struct sched *)racoon_malloc(sizeof(*new_sched)); | |
103 | if (new_sched == NULL) | |
104 | return 0; | |
105 | ||
106 | new_sched->ref = next_ref++; | |
107 | new_sched->dead = 0; | |
108 | new_sched->func = func; | |
109 | new_sched->param = param; | |
110 | new_sched->xtime = current_time() + tick; | |
111 | ||
52b7d2ce | 112 | /* add to schedule table */ |
65c25746 A |
113 | TAILQ_INSERT_TAIL(&sctree, new_sched, chain); |
114 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, tick * NSEC_PER_SEC), dispatch_get_main_queue(), | |
115 | ^{ | |
116 | timer_handler(new_sched); | |
117 | }); | |
118 | ||
119 | return new_sched->ref; | |
52b7d2ce A |
120 | } |
121 | ||
122 | /* get current time. | |
123 | * if defined FIXY2038PROBLEM, base time is the time when called sched_init(). | |
124 | * Otherwise, conform to time(3). | |
125 | */ | |
e8d9021d | 126 | time_t |
52b7d2ce A |
127 | current_time() |
128 | { | |
129 | time_t n; | |
130 | #ifdef FIXY2038PROBLEM | |
131 | time_t t; | |
65c25746 | 132 | |
52b7d2ce A |
133 | time(&n); |
134 | t = n - launched; | |
135 | if (t < 0) | |
136 | t += deltaY2038; | |
65c25746 | 137 | |
52b7d2ce A |
138 | return t; |
139 | #else | |
140 | return time(&n); | |
141 | #endif | |
142 | } | |
143 | ||
65c25746 A |
144 | int |
145 | sched_is_dead(schedule_ref ref) | |
52b7d2ce | 146 | { |
65c25746 A |
147 | struct sched *sc; |
148 | ||
149 | if (ref == 0) | |
150 | return 1; | |
151 | TAILQ_FOREACH(sc, &sctree, chain) { | |
152 | if (sc->ref == ref) { | |
153 | if (sc->dead) | |
154 | return 1; | |
155 | return 0; | |
156 | } | |
157 | } | |
158 | return 1; | |
159 | } | |
52b7d2ce | 160 | |
65c25746 A |
161 | |
162 | int | |
163 | sched_get_time(schedule_ref ref, time_t *time) | |
164 | { | |
165 | struct sched *sc; | |
166 | ||
167 | if (ref != 0) { | |
168 | TAILQ_FOREACH(sc, &sctree, chain) { | |
169 | if (sc->ref == ref) { | |
170 | if (sc->dead) | |
171 | return 0; | |
172 | *time = sc->xtime; | |
173 | return 1; | |
174 | } | |
175 | } | |
176 | } | |
177 | return 0; | |
52b7d2ce A |
178 | } |
179 | ||
52b7d2ce | 180 | void |
65c25746 | 181 | sched_kill(schedule_ref ref) |
52b7d2ce | 182 | { |
65c25746 A |
183 | struct sched *sc; |
184 | ||
185 | if (ref != 0) { | |
186 | TAILQ_FOREACH(sc, &sctree, chain) { | |
187 | if (sc->ref == ref) { | |
188 | sc->dead = 1; | |
189 | return; | |
190 | } | |
191 | } | |
52b7d2ce A |
192 | } |
193 | } | |
194 | ||
65c25746 A |
195 | void |
196 | sched_killall(void) | |
52b7d2ce | 197 | { |
65c25746 A |
198 | struct sched *sc; |
199 | ||
200 | TAILQ_FOREACH(sc, &sctree, chain) | |
201 | sc->dead = 1; | |
202 | } | |
52b7d2ce | 203 | |
52b7d2ce | 204 | |
65c25746 A |
205 | /* XXX this function is probably unnecessary. */ |
206 | void | |
207 | sched_scrub_param(void *param) | |
208 | { | |
209 | struct sched *sc; | |
210 | ||
211 | TAILQ_FOREACH(sc, &sctree, chain) { | |
212 | if (sc->param == param) { | |
213 | sc->dead = 1; | |
214 | } | |
52b7d2ce | 215 | } |
52b7d2ce A |
216 | } |
217 | ||
218 | /* initialize schedule table */ | |
219 | void | |
220 | sched_init() | |
221 | { | |
222 | #ifdef FIXY2038PROBLEM | |
223 | time(&launched); | |
65c25746 | 224 | |
52b7d2ce A |
225 | deltaY2038 = Y2038TIME_T - launched; |
226 | #endif | |
65c25746 | 227 | |
52b7d2ce | 228 | TAILQ_INIT(&sctree); |
52b7d2ce A |
229 | return; |
230 | } | |
231 |