diff options
Diffstat (limited to 'staging/time.c')
-rw-r--r-- | staging/time.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/staging/time.c b/staging/time.c new file mode 100644 index 0000000..4225b9e --- /dev/null +++ b/staging/time.c @@ -0,0 +1,211 @@ +/* + * Mausezahn - A fast versatile traffic generator + * Copyright (C) 2008-2010 Herbert Haas + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License version 2 as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, see http://www.gnu.org/licenses/gpl-2.0.html + * +*/ + + +#include "mz.h" + + +// Check if current system supports the nanosecond timer functions. +// Additionally, measure the precision. +// This function should be called upon program start. +// +int check_timer() +{ + struct timespec res; + int r; + +// Check if the glibc is recent enough: +#ifdef _POSIX_C_SOURCE + + if (_POSIX_C_SOURCE >= 199309L) { + r = clock_getres(CLOCK_MONOTONIC, &res); + if (r!=0) perror(" mz/check_timer:"); + if (verbose) { + fprintf(stderr, " This system supports a high resolution clock.\n"); + fprintf(stderr, " The clock resolution is %li nanoseconds.\n", + res.tv_nsec); + } + } + else { + fprintf(stderr, + " WARNING: Your system does NOT support the newer high resolution clock\n" + " Please inform the author: herbert@perihel.at\n"); + exit(1); + } +#endif + return 0; +} + + + + +// This is the replacement for gettimeofday() which would result in 'jumps' if +// the system clock is adjusted (e. g. via a NTP process) and finally the jitter +// measurement would include wrong datapoints. +// +// Furthermore the function below utilizes the newer hi-res nanosecond timers. +inline void getcurtime (struct mz_timestamp *t) +{ + struct timespec ct; + clock_gettime(CLOCK_MONOTONIC, &ct); + t->sec = ct.tv_sec; + t->nsec = ct.tv_nsec; +} + + + + +////////////////////////////////////////////////////////////////////////////////////// +// Purpose: Calculate time deltas of two timestamps stored in struct timeval. +// +// Subtract the "struct timeval" values X and Y, storing the result in RESULT, +// i. e. X-Y=RESULT. +// +// RETURN VALUES: +// +// Sign: 1 = negative, 0 = positive +// Error: -1 due to a wrong timestamp (i. e. nsec > 999999999L) +// +inline int timestamp_subtract (struct mz_timestamp *x, struct mz_timestamp *y, struct mz_timestamp *result) +{ + int32_t ndiff; + int sign=0, carry=0; + + // Check for wrong timestamps + if ((x->nsec>999999999L) || (y->nsec>999999999L)) return -1; + + if (y->sec > x->sec) sign=1; + else if ((y->sec == x->sec) && (y->nsec > x->nsec)) sign=1; + + ndiff = x->nsec - y->nsec; + if ((ndiff>0) && (sign)) carry=1; + if ((ndiff<0) && (sign)) ndiff = y->nsec - x->nsec; + if ((ndiff<0) && (!sign)) { + ndiff = 1000000000L + ndiff; + carry=1; + } + + if (sign) + result->sec = y->sec - x->sec - carry; + else + result->sec = x->sec - y->sec - carry; + + result->nsec = ndiff; + return sign; +} + + +// Add two variables of type struct mz_timestamp: x+y=result. +// +inline void timestamp_add (struct mz_timestamp *x, struct mz_timestamp *y, struct mz_timestamp *result) +{ + int carry=0; + u_int32_t c; + + c = x->nsec + y->nsec; + if (c>999999999L) { + carry=1; + result->nsec =c-1000000000; + } else result->nsec =c; + + result->sec = x->sec + y->sec + carry; +} + + + +// Returns a human readable timestamp in the string result. +// Optionally a prefix can be specified, for example if the +// timestamp is part of a filename. +// +// Example: +// char myTimeStamp[128]; +// +// timestamp_human(myTimeStamp, NULL); +// +// => "20080718_155521" +// +// /* or with prefix */ +// +// timestamp_human(myTimeStamp, "MZ_RTP_jitter_"); +// +// => "MZ_RTP_jitter_20080718_155521" +// +int timestamp_human(char* result, const char* prefix) +{ + time_t curtime; + struct tm curtime_broken; + char curtime_str[32]; + + time(&curtime); + localtime_r (&curtime, &curtime_broken); + + sprintf(curtime_str, "%4i%02i%02i-%02i%02i%02i", + curtime_broken.tm_year+1900, + curtime_broken.tm_mon+1, + curtime_broken.tm_mday, + curtime_broken.tm_hour, + curtime_broken.tm_min, + curtime_broken.tm_sec); + + if (prefix==NULL) + { + strncpy(result, curtime_str, 32); + } + else + { + strncpy(result, prefix, 32); + strncat(result, curtime_str, 32); + } + + return 0; +} + + +// Creates a human readable timestamp in the string result. +// Optionally a prefix can be specified, for example if the +// timestamp is part of a filename. +// +// Example: +// char myTimeStamp[9]; +// +// timestamp_hms (myTimeStamp); +// +// => "15:55:21" +int timestamp_hms(char* result) +{ + time_t curtime; + struct tm curtime_broken; + char curtime_str[32]; + + time(&curtime); + localtime_r (&curtime, &curtime_broken); + + sprintf(curtime_str, "%02i:%02i:%02i", + curtime_broken.tm_hour, + curtime_broken.tm_min, + curtime_broken.tm_sec); + + strncpy(result, curtime_str, 9); + + return 0; +} + + + + + |