kernel: Sync ACPICA with Intel's version 20140424.
[dragonfly.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: src/lib/libatm/timer.c,v 1.3.2.1 2001/09/28 16:52:10 dillon Exp $
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 Harp_timer      *harp_timer_head;
57 int             harp_timer_exec;
58
59
60 /*
61  * Process a HARP timer tick
62  *
63  * This function is called via the SIGALRM signal.  It increments
64  * harp_timer_exec.  The user should check this flag frequently and
65  * call timer_proc when it is set.
66  *
67  * Arguments:
68  *      None
69  *
70  * Returns:
71  *      None
72  *
73  */
74 static void
75 timer_tick(int signo __unused)
76 {
77         /*
78          * Bump the timer flag
79          */
80         harp_timer_exec++;
81 }
82
83
84 /*
85  * Process HARP timers
86  *
87  * This function is called after a SIGALRM signal is posted.  It runs
88  * down the list of timer entries, calling the specified functions
89  * for any timers that have expired.
90  *
91  * Arguments:
92  *      None
93  *
94  * Returns:
95  *      None
96  *
97  */
98 void
99 timer_proc(void)
100 {
101         Harp_timer      *htp;
102         void            (*f)();
103
104         /*
105          * Reset marks in all timers on the queue
106          */
107         for (htp = harp_timer_head; htp; htp = htp->ht_next) {
108                 htp->ht_mark = -1;
109         }
110
111         /*
112          * Run through timer chain decrementing each timer.
113          * If an expired timer is found, take the timer block
114          * off the chain and call the specified function.  A
115          * timer's action can result in other timers being
116          * cancelled (taken off the queue), so every time we
117          * call a user function, we start over from the top of
118          * the list.
119          */
120 timer_cont:
121         for (htp = harp_timer_head; htp; htp = htp->ht_next) {
122                 /*
123                  * Make sure we only process each entry once and
124                  * don't process entries that are put on the queue
125                  * by user functions we call for this tick
126                  */
127                 if (htp->ht_mark == -1) {
128                         /*
129                          * Decrement the timer and mark that we've
130                          * processed the entry
131                          */
132                         htp->ht_ticks -= harp_timer_exec;
133                         htp->ht_mark = 1;
134
135                         /*
136                          * Check whether the timer is expired
137                          */
138                         if (htp->ht_ticks <= 0) {
139                                 /*
140                                  * Unlink the timer block and call
141                                  * the user function
142                                  */
143                                 f = htp->ht_func;
144                                 UNLINK(htp, Harp_timer, harp_timer_head,
145                                                 ht_next);
146                                 f(htp);
147
148                                 /*
149                                  * Start over
150                                  */
151                                 goto timer_cont;
152                         }
153                 }
154         }
155
156         /*
157          * Reset the timer exec flag
158          */
159         harp_timer_exec = 0;
160 }
161
162
163 /*
164  * Start the timer
165  *
166  * Set up the SIGALRM signal handler and set up the real-time
167  * timer to tick once per second.
168  *
169  * Arguments:
170  *      None
171  *
172  * Returns:
173  *      0       success
174  *      errno   reason for failure
175  *
176  */
177 int
178 init_timer(void)
179 {
180         int                     rc = 0;
181         struct itimerval        timeval;
182
183         /*
184          * Clear the timer flag
185          */
186         harp_timer_exec = 0;
187
188         /*
189          * Set up signal handler
190          */
191         if (signal(SIGALRM, timer_tick) == SIG_ERR) {
192                 return(errno);
193         }
194
195         /*
196          * Start timer
197          */
198         timeval.it_value.tv_sec = 1;
199         timeval.it_value.tv_usec = 0;
200         timeval.it_interval.tv_sec = 1;
201         timeval.it_interval.tv_usec = 0;
202
203         if (setitimer(ITIMER_REAL, &timeval,
204                         NULL) == -1) {
205                 rc = errno;
206                 (void)signal(SIGALRM, SIG_DFL);
207         }
208
209         return(rc);
210 }
211
212
213 /*
214  * Block timers from firing
215  *
216  * Block the SIGALRM signal.
217  *
218  * Arguments:
219  *      None
220  *
221  * Returns:
222  *      mask    the previous blocked signal mask
223  *
224  */
225 int
226 block_timer(void)
227 {
228         /*
229          * Block the SIGALRM signal
230          */
231         return(sigblock(sigmask(SIGALRM)));
232 }
233
234
235 /*
236  * Re-enable timers
237  *
238  * Restore the signal mask (presumably one that was returned by
239  * block_timer).
240  *
241  * Arguments:
242  *      mask    the signal mask to be restored
243  *
244  * Returns:
245  *      mask    the previous blocked signal mask
246  *
247  */
248 void
249 enable_timer(int mask)
250 {
251         /*
252          * Set the signal mask
253          */
254         sigsetmask(mask);
255
256         return;
257 }