]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libatm/timer.c
This commit was generated by cvs2svn to compensate for changes in r57416,
[FreeBSD/FreeBSD.git] / lib / libatm / timer.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD$
27  *
28  */
29
30 /*
31  * User Space Library Functions
32  * ----------------------------
33  *
34  * Timer functions
35  *
36  */
37
38 #include <sys/types.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
41 #include <net/if.h>
42 #include <netinet/in.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_if.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_sys.h>
49 #include <netatm/atm_ioctl.h>
50
51 #include <errno.h>
52 #include <signal.h>
53
54 #include "libatm.h"
55
56 #ifndef lint
57 __RCSID("@(#) $FreeBSD$");
58 #endif
59
60
61 Harp_timer      *harp_timer_head;
62 int             harp_timer_exec;
63
64
65 /*
66  * Process a HARP timer tick
67  *
68  * This function is called via the SIGALRM signal.  It increments
69  * harp_timer_exec.  The user should check this flag frequently and
70  * call timer_proc when it is set.
71  *
72  * Arguments:
73  *      None
74  *
75  * Returns:
76  *      None
77  *
78  */
79 static void
80 timer_tick()
81 {
82         /*
83          * Bump the timer flag
84          */
85         harp_timer_exec++;
86 }
87
88
89 /*
90  * Process HARP timers
91  *
92  * This function is called after a SIGALRM signal is posted.  It runs
93  * down the list of timer entries, calling the specified functions
94  * for any timers that have expired.
95  *
96  * Arguments:
97  *      None
98  *
99  * Returns:
100  *      None
101  *
102  */
103 void
104 timer_proc()
105 {
106         Harp_timer      *htp;
107         void            (*f)();
108
109         /*
110          * Reset marks in all timers on the queue
111          */
112         for (htp = harp_timer_head; htp; htp = htp->ht_next) {
113                 htp->ht_mark = -1;
114         }
115
116         /*
117          * Run through timer chain decrementing each timer.
118          * If an expired timer is found, take the timer block
119          * off the chain and call the specified function.  A
120          * timer's action can result in other timers being
121          * cancelled (taken off the queue), so every time we
122          * call a user function, we start over from the top of
123          * the list.
124          */
125 timer_cont:
126         for (htp = harp_timer_head; htp; htp = htp->ht_next) {
127                 /*
128                  * Make sure we only process each entry once and
129                  * don't process entries that are put on the queue
130                  * by user functions we call for this tick
131                  */
132                 if (htp->ht_mark == -1) {
133                         /*
134                          * Decrement the timer and mark that we've
135                          * processed the entry
136                          */
137                         htp->ht_ticks -= harp_timer_exec;
138                         htp->ht_mark = 1;
139
140                         /*
141                          * Check whether the timer is expired
142                          */
143                         if (htp->ht_ticks <= 0) {
144                                 /*
145                                  * Unlink the timer block and call
146                                  * the user function
147                                  */
148                                 f = htp->ht_func;
149                                 UNLINK(htp, Harp_timer, harp_timer_head,
150                                                 ht_next);
151                                 f(htp);
152
153                                 /*
154                                  * Start over
155                                  */
156                                 goto timer_cont;
157                         }
158                 }
159         }
160
161         /*
162          * Reset the timer exec flag
163          */
164         harp_timer_exec = 0;
165 }
166
167
168 /*
169  * Start the timer
170  *
171  * Set up the SIGALRM signal handler and set up the real-time
172  * timer to tick once per second.
173  *
174  * Arguments:
175  *      None
176  *
177  * Returns:
178  *      0       success
179  *      errno   reason for failure
180  *
181  */
182 int
183 init_timer()
184 {
185         int                     rc = 0;
186         struct itimerval        timeval;
187
188         /*
189          * Clear the timer flag
190          */
191         harp_timer_exec = 0;
192
193         /*
194          * Set up signal handler
195          */
196         if ((int)signal(SIGALRM, timer_tick) == -1) {
197                 return(errno);
198         }
199
200         /*
201          * Start timer
202          */
203         timeval.it_value.tv_sec = 1;
204         timeval.it_value.tv_usec = 0;
205         timeval.it_interval.tv_sec = 1;
206         timeval.it_interval.tv_usec = 0;
207
208         if (setitimer(ITIMER_REAL, &timeval,
209                         (struct itimerval *)0) == -1) {
210                 rc = errno;
211                 (void)signal(SIGALRM, SIG_DFL);
212         }
213
214         return(rc);
215 }
216
217
218 /*
219  * Block timers from firing
220  *
221  * Block the SIGALRM signal.
222  *
223  * Arguments:
224  *      None
225  *
226  * Returns:
227  *      mask    the previous blocked signal mask
228  *
229  */
230 int
231 block_timer()
232 {
233         /*
234          * Block the SIGALRM signal
235          */
236         return(sigblock(sigmask(SIGALRM)));
237 }
238
239
240 /*
241  * Re-enable timers
242  *
243  * Restore the signal mask (presumably one that was returned by
244  * block_timer).
245  *
246  * Arguments:
247  *      mask    the signal mask to be restored
248  *
249  * Returns:
250  *      mask    the previous blocked signal mask
251  *
252  */
253 void
254 enable_timer(mask)
255         int     mask;
256 {
257         /*
258          * Set the signal mask
259          */
260         sigsetmask(mask);
261
262         return;
263 }