source: trunk/minix/servers/inet/clock.c@ 20

Last change on this file since 20 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 4.1 KB
RevLine 
[9]1/*
2clock.c
3
4Copyright 1995 Philip Homburg
5*/
6
7#include "inet.h"
8#include "proto.h"
9#include "generic/assert.h"
10#include "generic/buf.h"
11#include "generic/clock.h"
12#include "generic/type.h"
13
14THIS_FILE
15
16PUBLIC int clck_call_expire;
17
18PRIVATE time_t curr_time;
19PRIVATE time_t prev_time;
20PRIVATE timer_t *timer_chain;
21PRIVATE time_t next_timeout;
22#ifdef __minix_vmd
23PRIVATE int clck_tasknr= ANY;
24#endif
25
26FORWARD _PROTOTYPE( void clck_fast_release, (timer_t *timer) );
27FORWARD _PROTOTYPE( void set_timer, (void) );
28
29PUBLIC void clck_init()
30{
31 int r;
32
33 clck_call_expire= 0;
34 curr_time= 0;
35 prev_time= 0;
36 next_timeout= 0;
37 timer_chain= 0;
38
39#ifdef __minix_vmd
40 r= sys_findproc(CLOCK_NAME, &clck_tasknr, 0);
41 if (r != OK)
42 ip_panic(( "unable to find clock task: %d\n", r ));
43#endif
44}
45
46PUBLIC time_t get_time()
47{
48 if (!curr_time)
49 {
50#ifdef __minix_vmd
51 static message mess;
52
53 mess.m_type= GET_UPTIME;
54 if (sendrec (clck_tasknr, &mess) < 0)
55 ip_panic(("unable to sendrec"));
56 if (mess.m_type != OK)
57 ip_panic(("can't read clock"));
58 curr_time= mess.NEW_TIME;
59#else /* Minix 3 */
60 int s;
61 if ((s=getuptime(&curr_time)) != OK)
62 ip_panic(("can't read clock"));
63#endif
64 assert(curr_time >= prev_time);
65 }
66 return curr_time;
67}
68
69PUBLIC void set_time (tim)
70time_t tim;
71{
72 if (!curr_time && tim >= prev_time)
73 {
74 /* Some code assumes that no time elapses while it is
75 * running.
76 */
77 curr_time= tim;
78 }
79 else if (!curr_time)
80 {
81 DBLOCK(0x20, printf("set_time: new time %ld < prev_time %ld\n",
82 tim, prev_time));
83 }
84}
85
86PUBLIC void reset_time()
87{
88 prev_time= curr_time;
89 curr_time= 0;
90}
91
92PUBLIC void clck_timer(timer, timeout, func, fd)
93timer_t *timer;
94time_t timeout;
95timer_func_t func;
96int fd;
97{
98 timer_t *timer_index;
99
100 if (timer->tim_active)
101 clck_fast_release(timer);
102 assert(!timer->tim_active);
103
104 timer->tim_next= 0;
105 timer->tim_func= func;
106 timer->tim_ref= fd;
107 timer->tim_time= timeout;
108 timer->tim_active= 1;
109
110 if (!timer_chain)
111 timer_chain= timer;
112 else if (timeout < timer_chain->tim_time)
113 {
114 timer->tim_next= timer_chain;
115 timer_chain= timer;
116 }
117 else
118 {
119 timer_index= timer_chain;
120 while (timer_index->tim_next &&
121 timer_index->tim_next->tim_time < timeout)
122 timer_index= timer_index->tim_next;
123 timer->tim_next= timer_index->tim_next;
124 timer_index->tim_next= timer;
125 }
126 if (next_timeout == 0 || timer_chain->tim_time < next_timeout)
127 set_timer();
128}
129
130PUBLIC void clck_tick (mess)
131message *mess;
132{
133 next_timeout= 0;
134 set_timer();
135}
136
137PRIVATE void clck_fast_release (timer)
138timer_t *timer;
139{
140 timer_t *timer_index;
141
142 if (!timer->tim_active)
143 return;
144
145 if (timer == timer_chain)
146 timer_chain= timer_chain->tim_next;
147 else
148 {
149 timer_index= timer_chain;
150 while (timer_index && timer_index->tim_next != timer)
151 timer_index= timer_index->tim_next;
152 assert(timer_index);
153 timer_index->tim_next= timer->tim_next;
154 }
155 timer->tim_active= 0;
156}
157
158PRIVATE void set_timer()
159{
160 time_t new_time;
161 time_t curr_time;
162
163 if (!timer_chain)
164 return;
165
166 curr_time= get_time();
167 new_time= timer_chain->tim_time;
168 if (new_time <= curr_time)
169 {
170 clck_call_expire= 1;
171 return;
172 }
173
174 if (next_timeout == 0 || new_time < next_timeout)
175 {
176#ifdef __minix_vmd
177 static message mess;
178
179 next_timeout= new_time;
180
181 new_time -= curr_time;
182
183 mess.m_type= SET_SYNC_AL;
184 mess.CLOCK_PROC_NR= this_proc;
185 mess.DELTA_TICKS= new_time;
186 if (sendrec (clck_tasknr, &mess) < 0)
187 ip_panic(("unable to sendrec"));
188 if (mess.m_type != OK)
189 ip_panic(("can't set timer"));
190#else /* Minix 3 */
191 next_timeout= new_time;
192 new_time -= curr_time;
193
194 if (sys_setalarm(new_time, 0) != OK)
195 ip_panic(("can't set timer"));
196#endif
197 }
198}
199
200PUBLIC void clck_untimer (timer)
201timer_t *timer;
202{
203 clck_fast_release (timer);
204 set_timer();
205}
206
207PUBLIC void clck_expire_timers()
208{
209 time_t curr_time;
210 timer_t *timer_index;
211
212 clck_call_expire= 0;
213
214 if (timer_chain == NULL)
215 return;
216
217 curr_time= get_time();
218 while (timer_chain && timer_chain->tim_time<=curr_time)
219 {
220 assert(timer_chain->tim_active);
221 timer_chain->tim_active= 0;
222 timer_index= timer_chain;
223 timer_chain= timer_chain->tim_next;
224 (*timer_index->tim_func)(timer_index->tim_ref, timer_index);
225 }
226 set_timer();
227}
228
229/*
230 * $PchId: clock.c,v 1.10 2005/06/28 14:23:40 philip Exp $
231 */
Note: See TracBrowser for help on using the repository browser.