File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / utils.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:19:56 2012 UTC (12 years, 4 months ago) by misho
Branches: bmon, MAIN
CVS tags: v2_1_0p0, v2_1_0, HEAD
bmon

    1: /*
    2:  * utils.c             General purpose utilities
    3:  *
    4:  * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a
    7:  * copy of this software and associated documentation files (the "Software"),
    8:  * to deal in the Software without restriction, including without limitation
    9:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   10:  * and/or sell copies of the Software, and to permit persons to whom the
   11:  * Software is furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included
   14:  * in all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   17:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   21:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   22:  * DEALINGS IN THE SOFTWARE.
   23:  */
   24: 
   25: #include <bmon/bmon.h>
   26: #include <bmon/conf.h>
   27: #include <bmon/utils.h>
   28: 
   29: void * xcalloc(size_t n, size_t s)
   30: {
   31: 	void *d = calloc(n, s);
   32: 
   33: 	if (NULL == d) {
   34: 		fprintf(stderr, "xalloc: Out of memory\n");
   35: 		exit(ENOMEM);
   36: 	}
   37: 
   38: 	return d;
   39: }
   40: 
   41: void * xrealloc(void *p, size_t s)
   42: {
   43: 	void *d = realloc(p, s);
   44: 
   45: 	if (NULL == d) {
   46: 		fprintf(stderr, "xrealloc: Out of memory!\n");
   47: 		exit(ENOMEM);
   48: 	}
   49: 
   50: 	return d;
   51: }
   52: 
   53: void xfree(void *d)
   54: {
   55: 	if (d)
   56: 		free(d);
   57: }
   58: 
   59: inline float ts_to_float(timestamp_t *src)
   60: {
   61: 	return (float) src->tv_sec + ((float) src->tv_usec / 1000000.0f);
   62: }
   63: 
   64: inline void float_to_ts(timestamp_t *dst, float src)
   65: {
   66: 	dst->tv_sec = (time_t) src;
   67: 	dst->tv_usec = (src - ((float) ((time_t) src))) * 1000000.0f;
   68: }
   69: 
   70: inline void ts_add(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)
   71: {
   72: 	dst->tv_sec = src1->tv_sec + src2->tv_sec;
   73: 	dst->tv_usec = src1->tv_usec + src2->tv_usec;
   74: 
   75: 	if (dst->tv_usec >= 1000000) {
   76: 		dst->tv_sec++;
   77: 		dst->tv_usec -= 1000000;
   78: 	}
   79: }
   80: 
   81: inline void ts_sub(timestamp_t *dst, timestamp_t *src1, timestamp_t *src2)
   82: {
   83: 	dst->tv_sec = src1->tv_sec - src2->tv_sec;
   84: 	dst->tv_usec = src1->tv_usec - src2->tv_usec;
   85: 	if (dst->tv_usec <= -1000000) {
   86: 		dst->tv_sec--;
   87: 		dst->tv_usec += 1000000;
   88: 	}
   89: }
   90: 
   91: inline int ts_le(timestamp_t *a, timestamp_t *b)
   92: {
   93: 	if (a->tv_sec > b->tv_sec)
   94: 		return 0;
   95: 
   96: 	if (a->tv_sec < b->tv_sec || a->tv_usec <= b->tv_usec)
   97: 		return 1;
   98: 	
   99: 	return 0;
  100: }
  101: 
  102: inline void update_ts(timestamp_t *dst)
  103: {
  104: 	struct timeval tv;
  105: 
  106: 	gettimeofday(&tv, NULL);
  107: 
  108: 	dst->tv_sec = tv.tv_sec;
  109: 	dst->tv_usec = tv.tv_usec;
  110: }
  111: 	
  112: 
  113: float time_diff(timestamp_t *t1, timestamp_t *t2)
  114: {
  115: 	timestamp_t ts;
  116: 	ts_sub(&ts, t2, t1);
  117: 	return ts_to_float(&ts);
  118: }
  119: 
  120: float diff_now(timestamp_t *t1)
  121: {
  122: 	timestamp_t now;
  123: 	update_ts(&now);
  124: 	return time_diff(t1, &now);
  125: }
  126: 
  127: static inline b_cnt_t __divisor(int type, int exp)
  128: {
  129: 	static b_cnt_t cache[2][32];
  130: 
  131: 	if (exp) {
  132: 		if (!cache[get_use_si()][exp]) {
  133: 			cache[get_use_si()][exp] =
  134: 				(b_cnt_t) pow(get_use_si() ||
  135: 					       type == U_NUMBER ? 1000.0f : 1024.0f, exp);
  136: 		}
  137: 		return cache[get_use_si()][exp];
  138: 	} else
  139: 		return 1;
  140: }
  141: 
  142: static inline char * __unit(int type, int exp)
  143: {
  144: 	static char *u[2][3][32] = {
  145: 		[0] = { /* IEC */
  146: 			[U_BITS]   = { " b ", "Kib", "Mib", "Gib", "Tib" },
  147: 			[U_BYTES]  = { " B ", "KiB", "MiB", "GiB", "TiB" },
  148: 			[U_NUMBER] = { " ", "K", "M", "G", "T" },
  149: 		},
  150: 		[1] = { /* SI */
  151: 			[U_BITS]   = { "  b", "Kb ", "Mb ", "Gb ", "Tb " },
  152: 			[U_BYTES]  = { " B ", "KB ", "MB ", "GB ", "TB " },
  153: 			[U_NUMBER] = { " ", "K", "M", "G", "T" },
  154: 		}
  155: 	};
  156: 
  157: 	return u[get_use_si()][type][exp];
  158: 	
  159: }
  160: 
  161: b_cnt_t get_divisor(b_cnt_t hint, int unit, char **dst_unit, int *prec)
  162: {
  163: 	int yunit = get_y_unit();
  164: 
  165: 	if (prec)
  166: 		*prec = 2;
  167: 
  168: 	if (yunit == Y_DYNAMIC) {
  169: 		if (hint >= __divisor(unit, 3)) {
  170: 			*dst_unit = __unit(unit, 3);
  171: 			return __divisor(unit, 3);
  172: 		} else if (hint >= __divisor(unit, 2)) {
  173: 			*dst_unit = __unit(unit, 2);
  174: 			return __divisor(unit, 2);
  175: 		} else if (hint >= __divisor(unit, 1)) {
  176: 			*dst_unit = __unit(unit, 1);
  177: 			return __divisor(unit, 1);
  178: 		} else {
  179: 			*dst_unit = __unit(unit, 0);
  180: 			if (prec)
  181: 				*prec = 0;
  182: 			return 1;
  183: 		}
  184: 	} else {
  185: 		*dst_unit = __unit(unit, yunit);
  186: 		return __divisor(unit, yunit);
  187: 	}
  188: 
  189: 	return 1;
  190: }
  191: 
  192: double cancel_down(b_cnt_t l, int unit, char **dst_unit, int *prec)
  193: {
  194: 	return ((double) l / (double) get_divisor(l, unit, dst_unit, prec));
  195: }
  196: 
  197: const char * xinet_ntop(struct sockaddr *src, char *dst, socklen_t cnt)
  198: {
  199: 	void *s;
  200: 	int family;
  201: 
  202: 	if (src->sa_family == AF_INET6) {
  203: 		s = &((struct sockaddr_in6 *) src)->sin6_addr;
  204: 		family = AF_INET6;
  205: 	} else if (src->sa_family == AF_INET) {
  206: 		s = &((struct sockaddr_in *) src)->sin_addr;
  207: 		family = AF_INET;
  208: 	} else
  209: 		return NULL;
  210: 
  211: 	return inet_ntop(family, s, dst, cnt);
  212: }
  213: 
  214: b_cnt_t parse_size(const char *str)
  215: {
  216: 	char *p;
  217: 	b_cnt_t l = strtol(str, &p, 0);
  218: 	if (p == str)
  219: 		return -1;
  220: 
  221: 	if (*p) {
  222: 		if (!strcasecmp(p, "kb") || !strcasecmp(p, "k"))
  223: 			l *= 1024;
  224: 		else if (!strcasecmp(p, "gb") || !strcasecmp(p, "g"))
  225: 			l *= 1024*1024*1024;
  226: 		else if (!strcasecmp(p, "gbit"))
  227: 			l *= 1024*1024*1024/8;
  228: 		else if (!strcasecmp(p, "mb") || !strcasecmp(p, "m"))
  229: 			l *= 1024*1024;
  230: 		else if (!strcasecmp(p, "mbit"))
  231: 			l *= 1024*1024/8;
  232: 		else if (!strcasecmp(p, "kbit"))
  233: 			l *= 1024/8;
  234: 		else if (strcasecmp(p, "b") != 0)
  235: 			return -1;
  236: 	}
  237: 
  238: 	return l;
  239: }
  240: 
  241: #ifndef HAVE_STRDUP
  242: char *strdup(const char *s)
  243: {
  244: 	char *t = xcalloc(1, strlen(s) + 1);
  245: 	memcpy(t, s, strlen(s));
  246: 	return s;
  247: }
  248: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>