Home | History | Annotate | Download | only in ffsb-6.0-rc2
      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.. */
     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 
     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 
     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 
     62 void ffsb_statsc_destroy(ffsb_statsc_t * fsc)
     63 {
     64 	free(fsc->buckets);
     65 }
     66 
     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 
     76 int fsc_ignore_sys(ffsb_statsc_t * fsc, syscall_t s)
     77 {
     78 	return fsc->ignore_stats & (1 << s);
     79 }
     80 
     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 
     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 
    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 
    138 void ffsb_statsc_copy(ffsb_statsc_t * dest, ffsb_statsc_t * src)
    139 {
    140 	memcpy(dest, src, sizeof(*src));
    141 }
    142 
    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 
    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 
    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