1 /* Most of it stolen from Pierre Beyssac's bing */
2
3 /* $Id$ */
4
5 #include "echoping.h"
6
7 #define STATES 32
8
9 #include <time.h>
10 #include <ctype.h>
11
12 char *
random_string(unsigned length)13 random_string(unsigned length)
14 {
15
16 char *state = (char *) malloc(sizeof(char) * STATES);
17 char *result = (char *) malloc(length + 1);
18 int i, number;
19 unsigned seed = (unsigned) time((time_t *) NULL);
20
21 /* printf ("Seed is %u\n", seed); */
22
23 /* Initialize random generator */
24 (void) initstate(seed, state, STATES);
25
26 for (i = 0; i < length; i++) {
27 number = (random() % 94) + 33;
28 /* printf ("Number for %d is %d\n", i, number); */
29 result[i] = (char) number;
30 }
31 result[length] = '\0';
32
33 /* printf ("Result is %s\n", result); */
34
35 return result;
36
37 }
38
39 char *
to_upper(char * input)40 to_upper(char *input)
41 {
42 int c;
43 char *result;
44 result = (char *) malloc(strlen(input));
45 for (c = 0; c < strlen(input); c++)
46 result[c] = toupper((int) input[c]);
47 result[strlen(input)] = '\0';
48 return result;
49 }
50
51 /*
52 * tvsub -- Subtract 2 timeval structs: out = out - in. Out is assumed to be
53 * >= in. Comes from the bing program.
54 */
55 void
tvsub(out,in)56 tvsub(out, in)
57 struct timeval *out, *in;
58 {
59 if ((out->tv_usec -= in->tv_usec) < 0) {
60 --out->tv_sec;
61 out->tv_usec += 1000000;
62 }
63 out->tv_sec -= in->tv_sec;
64 }
65
66 /* tvadd -- Adds 2 timeval structs: out = out + in. */
67 void
tvadd(out,in)68 tvadd(out, in)
69 struct timeval *out, *in;
70 {
71 if ((out->tv_usec += in->tv_usec) >= 1000000) {
72 ++out->tv_sec;
73 out->tv_usec -= 1000000;
74 }
75 out->tv_sec += in->tv_sec;
76 }
77
78 /* tvavg -- Averages a timeval struct */
79 void
tvavg(out,number)80 tvavg(out, number)
81 struct timeval *out;
82 int number;
83 {
84 double result;
85 /*
86 * out->tv_sec = out->tv_sec/number; out->tv_usec =
87 * out->tv_usec/number;
88 */
89 result = (1000000 * out->tv_sec + out->tv_usec) / number;
90 /* printf ("Result of average is %f\n", result) */ ;
91 out->tv_sec = (long) (result / 1000000);
92 out->tv_usec = (long) (result - (out->tv_sec * 1000000));
93 }
94
95 /* tvstddev -- Computes the standard deviation of a set of results */
96 void
tvstddev(out,number,average,results)97 tvstddev(out, number, average, results)
98 struct timeval *out;
99 int number;
100 struct timeval average;
101 struct result *results;
102 {
103 int i;
104 struct timeval result = null_timeval;
105 struct timeval avg = null_timeval;
106 #ifdef DEBUG
107 struct timeval var = null_timeval;
108 #endif
109 struct timeval large, small;
110 double d_offset, d_square, d_variance = 0;
111 *out = null_timeval;
112 for (i = 0; i < number; i++) {
113 if (results[i].valid == 1) {
114 result = results[i].timevalue;
115 #ifdef DEBUG
116 printf("DEBUG: Value is %f (average is %f)\n", tv2double
117 (result), tv2double(average));
118 #endif
119 avg = average;
120 if (tvcmp(&result, &avg) == -1) {
121 small = result;
122 large = avg;
123 } else {
124 large = result;
125 small = avg;
126 }
127 tvsub(&large, &small);
128 #ifdef DEBUG
129 printf("abs offset is %f\n", tv2double(large));
130 #endif
131 d_offset = tv2double(large);
132 d_square = d_offset * d_offset;
133 d_variance += d_square;
134 #ifdef DEBUG
135 printf("variance is now %f\n", tv2double(var));
136 #endif
137 }
138 }
139 result = double2tv(sqrt(d_variance / (double) number));
140 out->tv_sec = result.tv_sec;
141 out->tv_usec = result.tv_usec;
142 }
143
144
145 /* tvstddevavg -- Computes the average of values within a set of results where the
146 * sample is within the given number of standard deviations from the average */
147 /* TODO: IWBN to return the number of excluded outliers */
148 void
tvstddevavg(out,number,average,results,n_stddev)149 tvstddevavg(out, number, average, results, n_stddev)
150 struct timeval *out; /* contains std dev on entry */
151 int number;
152 struct timeval average;
153 struct result *results;
154 double n_stddev;
155 {
156 int i, valid = 0;
157 struct timeval result; /* working value */
158 struct timeval var = null_timeval; /* result accumulator */
159 double x;
160 double maxdev = tv2double(*out) * n_stddev;
161
162 if (tvcmp(out, &null_timeval) == 0) {
163 /* if the SD is 0 then we just return the average */
164 *out = average;
165 return;
166 }
167
168 for (i = 0; i < number; i++) {
169 if (results[i].valid == 1) {
170 result = results[i].timevalue;
171 tvsub(&result, &average);
172 /* printf ("value is %f (stddev is %f)\n", tv2double (result), tv2double
173 * (stddev)); */
174 /* ensure that result (difference to average) is absolute value */
175 if (tvcmp(&result, &null_timeval) == -1) {
176 result = average;
177 tvsub(&result, &results[i].timevalue);
178 }
179 x = tv2double(result);
180 /* printf("value is %g maxdev %g\n",x,maxdev); */
181 if (x <= maxdev) {
182 /* deviation is less than stddev */
183 tvadd(&var, &results[i].timevalue);
184 valid++;
185 } else {
186 /* printf("dropped\n"); */
187 }
188 }
189 }
190 /* printf ("total is %f in %d samples\n", tv2double (var), valid); */
191 if (valid > 0) {
192 *out = double2tv(tv2double(var) / valid);
193 } else {
194 *out = null_timeval;
195 }
196
197 }
198
199 /* tvcmp -- Compares two timeval structs */
200 int
tvcmp(left,right)201 tvcmp(left, right)
202 struct timeval *left, *right;
203 {
204 if (left->tv_sec < right->tv_sec) {
205 return -1;
206 }
207 if (left->tv_sec > right->tv_sec) {
208 return 1;
209 }
210 if (left->tv_usec < right->tv_usec) {
211 return -1;
212 }
213 if (left->tv_usec > right->tv_usec) {
214 return 1;
215 }
216 return 0;
217
218 }
219
220 /* tvmin */
221 void
tvmin(champion,challenger)222 tvmin(champion, challenger)
223 struct timeval *champion, *challenger;
224 {
225 if (tvcmp(champion, challenger) == 1) {
226 champion->tv_sec = challenger->tv_sec;
227 champion->tv_usec = challenger->tv_usec;
228 }
229 }
230
231 /* tvmax */
232 void
tvmax(champion,challenger)233 tvmax(champion, challenger)
234 struct timeval *champion, *challenger;
235 {
236 if (tvcmp(champion, challenger) == -1) {
237 champion->tv_sec = challenger->tv_sec;
238 champion->tv_usec = challenger->tv_usec;
239 }
240 }
241
242 double
tv2double(tv)243 tv2double(tv)
244 struct timeval tv;
245 {
246 double result;
247 result =
248 (((((double) tv.tv_sec) * 1000000.0) + (double) tv.tv_usec) / 1000000.0);
249 /* printf ("Double is %9.3f\n", result); */
250 return result;
251 }
252
253 struct timeval
double2tv(x)254 double2tv(x)
255 double x;
256 {
257 struct timeval result;
258 result.tv_sec = (int) (x);
259 result.tv_usec = (int) ((x - result.tv_sec) * 1000000);
260 return result;
261 }
262