Initial revision
[ssr] / StraySrc / Libraries / Steel / c / alarm
1 /*
2 * alarm.c
3 *
4 * Calling routines at set times
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Steel library.
12 *
13 * Steel is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * Steel is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Steel. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 #include "alarm.h"
29 #include "mem.h"
30 #include "werr.h"
31 #include "msgs.h"
32 #include "os.h"
33 #include "swiv.h"
34 #include "swis.h"
35
36 typedef struct alarm__str
37 {
38 struct alarm__str *next;
39 alarm_handler proc;
40 void *handle;
41 int time;
42 }
43 alarm__str;
44
45 static alarm__str *alarm__all;
46
47 /*
48 * void alarm_init(void)
49 *
50 * Use
51 * None at all
52 */
53
54 void alarm_init(void)
55 {
56 /* Hmmm.... this *is* an interesting function */
57 }
58
59 /*
60 * int alarm_timenow(void)
61 *
62 * Use
63 * Reports the time right now
64 */
65
66 int alarm_timenow(void)
67 {
68 return (_swi(OS_ReadMonotonicTime,_return(0)));
69 }
70
71 /*
72 * int alarm_timedifference(int t1,int t2)
73 *
74 * Use
75 * Tells you the difference between two times. t2 is considered to be later
76 * than t1.
77 */
78
79 int alarm_timedifference(int t1,int t2)
80 {
81 /* --- Humm.... How to deal with wraparound --- *
82 *
83 * Answer: Ignore it and subtract -- mod 2^32 arithmetic + 2s complement
84 * sorts it all out for you.
85 */
86
87 return (t2-t1);
88 }
89
90 /*
91 * void alarm_set(int at,alarm_handler proc,void *handle)
92 *
93 * Use
94 * Sets up `proc' to be called at time `at', being passed `handle'.
95 */
96
97 void alarm_set(int at,alarm_handler proc,void *handle)
98 {
99 alarm__str *a=mem_alloc(sizeof(alarm__str));
100 alarm__str *p;
101 if (!a)
102 werr(FALSE,msgs_lookup("alarmNEM:Not enough memory for alarm"));
103 else
104 {
105 /* --- Fill in the structure --- */
106
107 a->time=at;
108 a->proc=proc;
109 a->handle=handle;
110
111 /* --- Scan the list and put the new node in the right place --- *
112 *
113 * Is this the right condition for the times?
114 */
115
116 p=(alarm__str *)&alarm__all;
117 while (p->next && p->next->time<at)
118 p=p->next;
119 a->next=p->next;
120 p->next=a;
121 }
122 }
123
124 /*
125 * void alarm_remove(int at,void *handle)
126 *
127 * Use
128 * Removes an alarm identified by a time and a handle
129 */
130
131 void alarm_remove(int at,void *handle)
132 {
133 alarm__str *p;
134 alarm__str *q;
135
136 p=(alarm__str *)&alarm__all;
137 while (p->next)
138 {
139 if (p->next->time==at && p->next->handle==handle)
140 {
141 q=p->next;
142 p->next=q->next;
143 mem_free(q);
144 return;
145 }
146 p=p->next;
147 }
148 }
149
150 /*
151 * void alarm_removeall(void *handle)
152 *
153 * Use
154 * Removes all alarms for the given handle
155 */
156
157 void alarm_removeall(void *handle)
158 {
159 alarm__str *p;
160 alarm__str *q;
161
162 p=(alarm__str *)&alarm__all;
163 while (p->next)
164 {
165 if (p->next->handle==handle)
166 {
167 q=p->next;
168 p->next=q->next;
169 mem_free(q);
170 }
171 else
172 p=p->next;
173 }
174 }
175
176 /*
177 * BOOL alarm_anypending(void *handle)
178 *
179 * Use
180 * Returns TRUE if there are alarms for the given handle
181 */
182
183 BOOL alarm_anypending(void *handle)
184 {
185 alarm__str *p=alarm__all;
186
187 while (p)
188 {
189 if (p->handle==handle)
190 return (TRUE);
191 p=p->next;
192 }
193 return (FALSE);
194 }
195
196 /*
197 * BOOL alarm_next(int *when)
198 *
199 * Use
200 * Informs the caller (a) if there are any alarms waiting, and (b) when
201 * the next one is.
202 *
203 * Parameters
204 * int *when == where to put the next time for an alarm (unchanged if no
205 * alarm is set)
206 *
207 * Returns
208 * TRUE if there are any alarms left
209 */
210
211 BOOL alarm_next(int *when)
212 {
213 if (alarm__all)
214 {
215 *when=alarm__all->time;
216 return (TRUE);
217 }
218 else
219 return (FALSE);
220 }
221
222 /*
223 * void alarm_callnext(void)
224 *
225 * Use
226 * Calls the next alarm and removes it from the list
227 */
228
229 void alarm_callnext(void)
230 {
231 alarm__str a;
232
233 if (!alarm__all)
234 return;
235
236 a=*alarm__all;
237 mem_free(alarm__all);
238 alarm__all=a.next;
239 a.proc(a.time,a.handle);
240 }