Removed definition "LIB= rpc". We want libc.a to contain librpc.a, not
[unix-history] / .ref-BSD-4_3_Net_2 / usr / src / usr.sbin / amd / amd / clock.c
CommitLineData
e1a31032 1/*
e1a31032
KM
2 * Copyright (c) 1989 Jan-Simon Pendry
3 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4 * Copyright (c) 1989 The Regents of the University of California.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry at Imperial College, London.
9 *
af359dea
C
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
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 * @(#)clock.c 5.3 (Berkeley) 5/12/91
39 *
40 * $Id: clock.c,v 5.2.1.5 91/05/07 22:17:49 jsp Alpha $
e1a31032 41 *
e1a31032
KM
42 */
43
44/*
45 * Callouts.
46 *
47 * Modelled on kernel object of the same name.
48 * See usual references.
49 *
50 * Use of a heap-based mechanism was rejected:
2664d859
JSP
51 * 1. more complex implementation needed.
52 * 2. not obvious that a list is too slow for Amd.
e1a31032
KM
53 */
54
55#include "am.h"
56
57typedef struct callout callout;
58struct callout {
59 callout *c_next; /* List of callouts */
60 void (*c_fn)(); /* Function to call */
61 voidp c_closure; /* Closure to pass to call */
62 time_t c_time; /* Time of call */
63 int c_id; /* Unique identifier */
64};
65
66static callout callouts; /* List of pending callouts */
67static callout *free_callouts; /* Cache of free callouts */
68static int nfree_callouts; /* Number on free list */
69static int callout_id; /* Next free callout identifier */
70time_t next_softclock; /* Time of next call to softclock() */
71
72/*
73 * Number of callout slots we keep on the free list
74 */
75#define CALLOUT_FREE_SLOP 10
76
77/*
2664d859 78 * Global assumption: valid id's are non-zero.
e1a31032
KM
79 */
80#define CID_ALLOC() (++callout_id)
81#define CID_UNDEF (0)
82
2664d859 83static callout *alloc_callout(P_void);
e1a31032
KM
84static callout *alloc_callout()
85{
86 callout *cp = free_callouts;
87 if (cp) {
88 --nfree_callouts;
89 free_callouts = free_callouts->c_next;
90 return cp;
91 }
92 return ALLOC(callout);
93}
94
2664d859 95static void free_callout P((callout *cp));
e1a31032
KM
96static void free_callout(cp)
97callout *cp;
98{
99 if (nfree_callouts > CALLOUT_FREE_SLOP) {
100 free((voidp) cp);
101 } else {
102 cp->c_next = free_callouts;
103 free_callouts = cp;
104 nfree_callouts++;
105 }
106}
107
108/*
109 * Schedule a callout.
110 *
111 * (*fn)(closure) will be called at clocktime() + secs
112 */
2664d859 113int timeout P((unsigned int secs, void (*fn)(), voidp closure));
e1a31032
KM
114int timeout(secs, fn, closure)
115unsigned int secs;
116void (*fn)();
117voidp closure;
118{
119 callout *cp, *cp2;
120 time_t t = clocktime() + secs;
121
122 /*
123 * Allocate and fill in a new callout structure
124 */
125 callout *cpnew = alloc_callout();
126 cpnew->c_closure = closure;
127 cpnew->c_fn = fn;
128 cpnew->c_time = t;
129 cpnew->c_id = CID_ALLOC();
130
131 if (t < next_softclock)
132 next_softclock = t;
133
134 /*
135 * Find the correct place in the list
136 */
137 for (cp = &callouts; cp2 = cp->c_next; cp = cp2)
138 if (cp2->c_time >= t)
139 break;
140
141 /*
142 * And link it in
143 */
144 cp->c_next = cpnew;
145 cpnew->c_next = cp2;
146
147 /*
148 * Return callout identifier
149 */
150 return cpnew->c_id;
151}
152
153/*
154 * De-schedule a callout
155 */
2664d859 156void untimeout P((int id));
e1a31032
KM
157void untimeout(id)
158int id;
159{
160 callout *cp, *cp2;
161 for (cp = &callouts; cp2 = cp->c_next; cp = cp2) {
162 if (cp2->c_id == id) {
163 cp->c_next = cp2->c_next;
164 free_callout(cp2);
165 break;
166 }
167 }
168}
169
2664d859
JSP
170/*
171 * Reschedule after clock changed
172 */
173void reschedule_timeouts P((time_t now, time_t then));
174void reschedule_timeouts(now, then)
175time_t now;
176time_t then;
177{
178 callout *cp;
179
180 for (cp = callouts.c_next; cp; cp = cp->c_next) {
181 if (cp->c_time >= now && cp->c_time <= then) {
182 plog(XLOG_WARNING, "job %d rescheduled to run immediately", cp->c_id);
183#ifdef DEBUG
184 dlog("rescheduling job %d back %d seconds",
185 cp->c_id, cp->c_time - now);
186#endif
187 next_softclock = cp->c_time = now;
188 }
189 }
190}
191
e1a31032
KM
192/*
193 * Clock handler
194 */
2664d859 195int softclock(P_void);
e1a31032
KM
196int softclock()
197{
198 time_t now;
199 callout *cp;
200
201 do {
202 if (task_notify_todo)
2664d859 203 do_task_notify();
e1a31032
KM
204
205 now = clocktime();
206
207 /*
208 * While there are more callouts waiting...
209 */
210 while ((cp = callouts.c_next) && cp->c_time <= now) {
211 /*
212 * Extract first from list, save fn & closure and
213 * unlink callout from list and free.
214 * Finally call function.
215 *
216 * The free is done first because
217 * it is quite common that the
218 * function will call timeout()
219 * and try to allocate a callout
220 */
221 void (*fn)() = cp->c_fn;
222 voidp closure = cp->c_closure;
223
224 callouts.c_next = cp->c_next;
225 free_callout(cp);
226#ifdef DEBUG
227 /*dlog("Calling %#x(%#x)", fn, closure);*/
228#endif /* DEBUG */
229 (*fn)(closure);
230 }
231
232 } while (task_notify_todo);
233
234 /*
235 * Return number of seconds to next event,
236 * or 0 if there is no event.
237 */
238 if (cp = callouts.c_next)
239 return cp->c_time - now;
240 return 0;
241}