1/* $NetBSD: schedule.c,v 1.4 2006/09/09 16:22:10 manu Exp $ */ 2 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> 47#include <dispatch/dispatch.h> 48 49#include "misc.h" 50#include "plog.h" 51#include "schedule.h" 52#include "var.h" 53#include "gcmalloc.h" 54#include "power_mgmt.h" 55#include "localconf.h" 56 57#if !defined(__LP64__) 58// year 2038 problem and fix for 32-bit only 59#define FIXY2038PROBLEM 60#endif 61 62 63extern int terminated; 64 65#ifdef FIXY2038PROBLEM 66#define Y2038TIME_T 0x7fffffff 67static time_t launched; /* time when the program launched. */ 68static time_t deltaY2038; 69#endif 70 71static TAILQ_HEAD(_schedtree, sched) sctree; 72 73 74void 75timer_handler(struct sched *sched) 76{ 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); 88} 89 90/* 91 * add new schedule to schedule table. 92 */ 93schedule_ref 94sched_new(time_t tick, void (*func) (void *), void *param) 95{ 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 112 /* add to schedule table */ 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; 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 */ 126time_t 127current_time() 128{ 129 time_t n; 130#ifdef FIXY2038PROBLEM 131 time_t t; 132 133 time(&n); 134 t = n - launched; 135 if (t < 0) 136 t += deltaY2038; 137 138 return t; 139#else 140 return time(&n); 141#endif 142} 143 144int 145sched_is_dead(schedule_ref ref) 146{ 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} 160 161 162int 163sched_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; 178} 179 180void 181sched_kill(schedule_ref ref) 182{ 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 } 192 } 193} 194 195void 196sched_killall(void) 197{ 198 struct sched *sc; 199 200 TAILQ_FOREACH(sc, &sctree, chain) 201 sc->dead = 1; 202} 203 204 205/* XXX this function is probably unnecessary. */ 206void 207sched_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 } 215 } 216} 217 218/* initialize schedule table */ 219void 220sched_init() 221{ 222#ifdef FIXY2038PROBLEM 223 time(&launched); 224 225 deltaY2038 = Y2038TIME_T - launched; 226#endif 227 228 TAILQ_INIT(&sctree); 229 return; 230} 231 232