"Fossies" - the Fresh Open Source Software Archive 
Member "httperf-0.9.0/src/timer.c" (7 Apr 2007, 4794 Bytes) of package /linux/www/old/httperf-0.9.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "timer.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 httperf -- a tool for measuring web server performance
3 Copyright 2000-2007 Hewlett-Packard Company and Contributors listed in
4 AUTHORS file. Originally contributed by David Mosberger-Tang
5
6 This file is part of httperf, a web server performance measurment
7 tool.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 In addition, as a special exception, the copyright holders give
15 permission to link the code of this work with the OpenSSL project's
16 "OpenSSL" library (or with modified versions of it that use the same
17 license as the "OpenSSL" library), and distribute linked combinations
18 including the two. You must obey the GNU General Public License in
19 all respects for all of the code used other than "OpenSSL". If you
20 modify this file, you may extend this exception to your version of the
21 file, but you are not obligated to do so. If you do not wish to do
22 so, delete this exception statement from your version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
28
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 02110-1301, USA
33 */
34
35 #include <assert.h>
36 #include <errno.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include <sys/time.h>
42
43 #include <httperf.h>
44 #include <timer.h>
45
46 #define WHEEL_SIZE 4096
47
48 #if 1
49 static Time now;
50 #endif
51 static Time next_tick;
52 static Timer *timer_free_list = 0;
53 static Timer *t_curr = 0;
54
55 /* What a wheel is made of, no? */
56 static Timer_Queue wheel[WHEEL_SIZE], *curr = 0;
57
58 static void
59 done (Timer *t)
60 {
61 t->q.next = timer_free_list;
62 t->q.prev = 0;
63 timer_free_list = t;
64 }
65
66 Time
67 timer_now_forced (void)
68 {
69 struct timeval tv;
70
71 gettimeofday (&tv, 0);
72 return tv.tv_sec + tv.tv_usec*1e-6;
73 }
74
75 Time
76 timer_now (void)
77 {
78 return now;
79 }
80
81 void
82 timer_init (void)
83 {
84 now = timer_now_forced ();
85 memset (wheel, 0, sizeof (wheel));
86 next_tick = timer_now () + TIMER_INTERVAL;
87 curr = wheel;
88 }
89
90 void
91 timer_tick (void)
92 {
93 Timer *t, *t_next;
94
95 assert (!t_curr);
96
97 now = timer_now_forced ();
98
99 while (timer_now () >= next_tick)
100 {
101 for (t = curr->next; t && t->delta == 0; t = t_next)
102 {
103 t_curr = t;
104 (*t->func) (t, t->arg);
105 t_next = t->q.next;
106 done (t);
107 }
108 t_curr = 0;
109 curr->next = t;
110 if (t)
111 {
112 t->q.prev = (Timer *) curr;
113 --t->delta;
114 }
115 next_tick += TIMER_INTERVAL;
116 if (++curr >= wheel + WHEEL_SIZE)
117 curr = wheel;
118 }
119 }
120
121 Timer*
122 timer_schedule (Timer_Callback timeout, Any_Type arg, Time delay)
123 {
124 Timer_Queue *spoke;
125 Timer *t, *p;
126 u_long ticks;
127 u_long delta;
128 Time behind;
129
130 if (timer_free_list)
131 {
132 t = timer_free_list;
133 timer_free_list = t->q.next;
134 }
135 else
136 {
137 t = malloc (sizeof (*t));
138 if (!t)
139 {
140 fprintf (stderr, "%s.timer_schedule: %s\n",
141 prog_name, strerror (errno));
142 return 0;
143 }
144 }
145 memset (t, 0, sizeof (*t));
146 t->func = timeout;
147 t->arg = arg;
148
149 behind = (timer_now () - next_tick);
150 if (behind > 0.0)
151 delay += behind;
152
153 if (delay < 0.0)
154 ticks = 1;
155 else
156 {
157 ticks = (delay + TIMER_INTERVAL / 2.0) * (1.0 / TIMER_INTERVAL);
158 if (!ticks)
159 ticks = 1; /* minimum delay is a tick */
160 }
161
162 spoke = curr + (ticks % WHEEL_SIZE);
163 if (spoke >= wheel + WHEEL_SIZE)
164 spoke -= WHEEL_SIZE;
165
166 delta = ticks / WHEEL_SIZE;
167 p = (Timer *) spoke;
168 while (p->q.next && delta > p->q.next->delta)
169 {
170 delta -= p->q.next->delta;
171 p = p->q.next;
172 }
173 t->q.next = p->q.next;
174 t->q.prev = p;
175 p->q.next = t;
176 t->delta = delta;
177 if (t->q.next)
178 {
179 t->q.next->q.prev = t;
180 t->q.next->delta -= delta;
181 }
182
183 if (DBG > 2)
184 fprintf (stderr, "timer_schedule: t=%p, delay=%gs, arg=%lx\n",
185 t, delay, arg.l);
186
187 return t;
188 }
189
190 void
191 timer_cancel (Timer *t)
192 {
193 if (DBG > 2)
194 fprintf (stderr, "timer_cancel: t=%p\n", t);
195
196 assert (t->q.prev);
197
198 /* A module MUST NOT call timer_cancel() for a timer that is
199 currently being processed (whose timeout has expired). */
200 if (t_curr == t)
201 {
202 fprintf (stderr, "timer_cancel() called on currently active timer!\n");
203 return;
204 }
205
206 if (t->q.next)
207 {
208 t->q.next->delta += t->delta;
209 t->q.next->q.prev = t->q.prev;
210 }
211 t->q.prev->q.next = t->q.next;
212 done (t);
213 }