/*** This file is part of avahi. avahi is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. avahi 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with avahi; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. ***/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <pthread.h> #include <stdlib.h> #include <assert.h> #include "timeval.h" int avahi_timeval_compare(const struct timeval *a, const struct timeval *b) { assert(a); assert(b); if (a->tv_sec < b->tv_sec) return -1; if (a->tv_sec > b->tv_sec) return 1; if (a->tv_usec < b->tv_usec) return -1; if (a->tv_usec > b->tv_usec) return 1; return 0; } AvahiUsec avahi_timeval_diff(const struct timeval *a, const struct timeval *b) { assert(a); assert(b); if (avahi_timeval_compare(a, b) < 0) return - avahi_timeval_diff(b, a); return ((AvahiUsec) a->tv_sec - b->tv_sec)*1000000 + a->tv_usec - b->tv_usec; } struct timeval* avahi_timeval_add(struct timeval *a, AvahiUsec usec) { AvahiUsec u; assert(a); u = usec + a->tv_usec; if (u < 0) { a->tv_usec = (long) (1000000 + (u % 1000000)); a->tv_sec += (long) (-1 + (u / 1000000)); } else { a->tv_usec = (long) (u % 1000000); a->tv_sec += (long) (u / 1000000); } return a; } AvahiUsec avahi_age(const struct timeval *a) { struct timeval now; assert(a); gettimeofday(&now, NULL); return avahi_timeval_diff(&now, a); } struct timeval *avahi_elapse_time(struct timeval *tv, unsigned msec, unsigned jitter) { assert(tv); gettimeofday(tv, NULL); if (msec) avahi_timeval_add(tv, (AvahiUsec) msec*1000); if (jitter) { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; static int last_rand; static time_t timestamp = 0; time_t now; int r; now = time(NULL); pthread_mutex_lock(&mutex); if (now >= timestamp + 10) { timestamp = now; last_rand = rand(); } r = last_rand; pthread_mutex_unlock(&mutex); /* We use the same jitter for 10 seconds. That way our * time events elapse in bursts which has the advantage that * packet data can be aggregated better */ avahi_timeval_add(tv, (AvahiUsec) (jitter*1000.0*r/(RAND_MAX+1.0))); } return tv; }