• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <stdio.h>
2 #include <assert.h>
3 #include <limits.h>
4 #include "ffsb_stats.h"
5 #include "util.h"
6 
7 char *syscall_names[] = {
8 	"open",
9 	"read",
10 	"write",
11 	"create",
12 	"lseek",
13 	"unlink",
14 	"close",
15 	"stat",
16 };
17 
18 /* yuck, just for the parser anyway.. */
ffsb_stats_str2syscall(char * str,syscall_t * sys)19 int ffsb_stats_str2syscall(char *str, syscall_t * sys)
20 {
21 	int i;
22 	int ret;
23 	for (i = 0; i < FFSB_NUM_SYSCALLS; i++) {
24 		ret = strncasecmp(syscall_names[i], str,
25 				  strlen(syscall_names[i]));
26 		/* printf("%s = syscall_names[%d] vs %str ret = %d\n",
27 		 * syscall_names[i],i,str,ret);
28 		 */
29 		if (0 == ret) {
30 			*sys = (syscall_t) i;	/* ewww */
31 			/* printf("matched syscall %s\n",syscall_names[i]); */
32 			return 1;
33 		}
34 	}
35 	printf("warning: failed to get match for syscall %s\n", str);
36 	return 0;
37 }
38 
ffsb_statsc_init(ffsb_statsc_t * fsc)39 void ffsb_statsc_init(ffsb_statsc_t * fsc)
40 {
41 	fsc->num_buckets = 0;
42 	fsc->buckets = NULL;
43 	fsc->ignore_stats = 0;
44 }
45 
ffsb_statsc_addbucket(ffsb_statsc_t * fsc,uint32_t min,uint32_t max)46 void ffsb_statsc_addbucket(ffsb_statsc_t * fsc, uint32_t min, uint32_t max)
47 {
48 	struct stat_bucket *temp;
49 	fsc->num_buckets++;
50 
51 	/* printf("ffsb_realloc(): fsc_buckets = %d\n",fsc->num_buckets); */
52 	temp = ffsb_realloc(fsc->buckets, sizeof(struct stat_bucket) *
53 			    fsc->num_buckets);
54 
55 	fsc->buckets = temp;
56 
57 	/* Convert to micro-secs from milli-secs */
58 	fsc->buckets[fsc->num_buckets - 1].min = min;
59 	fsc->buckets[fsc->num_buckets - 1].max = max;
60 }
61 
ffsb_statsc_destroy(ffsb_statsc_t * fsc)62 void ffsb_statsc_destroy(ffsb_statsc_t * fsc)
63 {
64 	free(fsc->buckets);
65 }
66 
ffsb_statsc_ignore_sys(ffsb_statsc_t * fsc,syscall_t s)67 void ffsb_statsc_ignore_sys(ffsb_statsc_t * fsc, syscall_t s)
68 {
69 	/* printf("fsis: oring 0x%x with 0x%x\n",
70 	 *      fsc->ignore_stats,
71 	 *      (1 << s ) );
72 	 */
73 	fsc->ignore_stats |= (1 << s);
74 }
75 
fsc_ignore_sys(ffsb_statsc_t * fsc,syscall_t s)76 int fsc_ignore_sys(ffsb_statsc_t * fsc, syscall_t s)
77 {
78 	return fsc->ignore_stats & (1 << s);
79 }
80 
ffsb_statsd_init(ffsb_statsd_t * fsd,ffsb_statsc_t * fsc)81 void ffsb_statsd_init(ffsb_statsd_t * fsd, ffsb_statsc_t * fsc)
82 {
83 	int i;
84 	memset(fsd, 0, sizeof(*fsd));
85 
86 	for (i = 0; i < FFSB_NUM_SYSCALLS; i++) {
87 		fsd->totals[i] = 0;
88 		fsd->mins[i] = UINT_MAX;
89 		fsd->maxs[i] = 0;
90 		fsd->buckets[i] = ffsb_malloc(sizeof(uint32_t) *
91 					      fsc->num_buckets);
92 		assert(fsd->buckets[i] != NULL);
93 
94 		memset(fsd->buckets[i], 0, sizeof(uint32_t) * fsc->num_buckets);
95 	}
96 	fsd->config = fsc;
97 }
98 
ffsb_statsd_destroy(ffsb_statsd_t * fsd)99 void ffsb_statsd_destroy(ffsb_statsd_t * fsd)
100 {
101 	int i;
102 	for (i = 0; i < FFSB_NUM_SYSCALLS; i++)
103 		free(fsd->buckets[i]);
104 }
105 
ffsb_add_data(ffsb_statsd_t * fsd,syscall_t s,uint32_t value)106 void ffsb_add_data(ffsb_statsd_t * fsd, syscall_t s, uint32_t value)
107 {
108 	unsigned num_buckets, i;
109 	struct stat_bucket *bucket_defs;
110 
111 	if (!fsd || fsc_ignore_sys(fsd->config, s))
112 		return;
113 
114 	if (value < fsd->mins[s])
115 		fsd->mins[s] = value;
116 	if (value > fsd->maxs[s])
117 		fsd->maxs[s] = value;
118 
119 	fsd->counts[s]++;
120 	fsd->totals[s] += value;
121 
122 	if (fsd->config->num_buckets == 0)
123 		return;
124 
125 	num_buckets = fsd->config->num_buckets;
126 	bucket_defs = fsd->config->buckets;
127 
128 	for (i = 0; i < num_buckets; i++) {
129 		struct stat_bucket *b = &bucket_defs[i];
130 
131 		if (value <= b->max && value >= b->min) {
132 			fsd->buckets[s][i]++;
133 			break;
134 		}
135 	}
136 }
137 
ffsb_statsc_copy(ffsb_statsc_t * dest,ffsb_statsc_t * src)138 void ffsb_statsc_copy(ffsb_statsc_t * dest, ffsb_statsc_t * src)
139 {
140 	memcpy(dest, src, sizeof(*src));
141 }
142 
ffsb_statsd_add(ffsb_statsd_t * dest,ffsb_statsd_t * src)143 void ffsb_statsd_add(ffsb_statsd_t * dest, ffsb_statsd_t * src)
144 {
145 	int i, j;
146 	unsigned num_buckets;
147 	if (dest->config != src->config)
148 		printf("ffsb_statsd_add: warning configs do not"
149 		       "match for data being collected\n");
150 
151 	num_buckets = dest->config->num_buckets;
152 
153 	for (i = 0; i < FFSB_NUM_SYSCALLS; i++) {
154 		dest->counts[i] += src->counts[i];
155 		dest->totals[i] += src->totals[i];
156 
157 		if (src->mins[i] < dest->mins[i])
158 			dest->mins[i] = src->mins[i];
159 		if (src->maxs[i] > dest->maxs[i])
160 			dest->maxs[i] = src->maxs[i];
161 
162 		for (j = 0; j < num_buckets; j++)
163 			dest->buckets[i][j] += src->buckets[i][j];
164 	}
165 }
166 
print_buckets_helper(ffsb_statsc_t * fsc,uint32_t * buckets)167 static void print_buckets_helper(ffsb_statsc_t * fsc, uint32_t * buckets)
168 {
169 	int i;
170 	if (fsc->num_buckets == 0) {
171 		printf("   -\n");
172 		return;
173 	}
174 	for (i = 0; i < fsc->num_buckets; i++) {
175 		struct stat_bucket *sb = &fsc->buckets[i];
176 		printf("\t\t msec_range[%d]\t%f - %f : %8u\n",
177 		       i, (double)sb->min / 1000.0f, (double)sb->max / 1000.0f,
178 		       buckets[i]);
179 	}
180 	printf("\n");
181 }
182 
ffsb_statsd_print(ffsb_statsd_t * fsd)183 void ffsb_statsd_print(ffsb_statsd_t * fsd)
184 {
185 	int i;
186 	printf("\nSystem Call Latency statistics in millisecs\n" "=====\n");
187 	printf("\t\tMin\t\tAvg\t\tMax\t\tTotal Calls\n");
188 	printf("\t\t========\t========\t========\t============\n");
189 	for (i = 0; i < FFSB_NUM_SYSCALLS; i++)
190 		if (fsd->counts[i]) {
191 			printf("[%7s]\t%05f\t%05lf\t%05f\t%12u\n",
192 			       syscall_names[i], (float)fsd->mins[i] / 1000.0f,
193 			       (fsd->totals[i] / (1000.0f *
194 						  (double)fsd->counts[i])),
195 			       (float)fsd->maxs[i] / 1000.0f, fsd->counts[i]);
196 			print_buckets_helper(fsd->config, fsd->buckets[i]);
197 		}
198 }
199 
200 #if 0				/* Testing */
201 
202 void *ffsb_malloc(size_t s)
203 {
204 	void *p = malloc(s);
205 	assert(p != NULL);
206 	return p;
207 }
208 
209 int main(int arc, char *argv[])
210 {
211 	ffsb_statsc_t fsc;
212 	ffsb_statsd_t fsd;
213 	int i;
214 
215 	printf("init\n");
216 
217 	ffsb_statsc_init(&fsc, 10);
218 	ffsb_statsc_setbucket(&fsc, 0, 0.0f, 50.0f);
219 	ffsb_statsc_setbucket(&fsc, 1, 50.0f, 10000.0f);
220 	ffsb_statsc_setbucket(&fsc, 2, 0.1f, 0.2f);
221 	ffsb_statsc_setbucket(&fsc, 3, 0.0f, 50.0f);
222 	ffsb_statsc_setbucket(&fsc, 4, 50.0f, 10000.0f);
223 	ffsb_statsc_setbucket(&fsc, 5, 0.1f, 0.2f);
224 	ffsb_statsc_setbucket(&fsc, 6, 0.0f, 50.0f);
225 	ffsb_statsc_setbucket(&fsc, 7, 50.0f, 10000.0f);
226 	ffsb_statsc_setbucket(&fsc, 8, 0.1f, 0.2f);
227 	ffsb_statsc_setbucket(&fsc, 9, 50.0f, 10000.0f);
228 	ffsb_statsd_init(&fsd, &fsc);
229 
230 	printf("test\n");
231 	for (i = 0; i < 50000000; i++)
232 		ffsb_add_data(&fsd, SYS_READ, (float)i);
233 
234 	printf("cleanup\n");
235 	ffsb_statsd_destroy(&fsd);
236 	ffsb_statsc_destroy(&fsc);
237 	return 0;
238 }
239 
240 #endif /* Testing */
241