]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
timeval_func: move all timeval manipulation to separate file
authorVadim Fedorenko <vadfed@meta.com>
Tue, 18 Apr 2023 13:50:12 +0000 (06:50 -0700)
committerVadim Fedorenko <vadfed@meta.com>
Wed, 26 Apr 2023 10:23:41 +0000 (03:23 -0700)
There are several definitions of the same functions manipulating timeval
structures. Let's move them to separate file and arrange the code
preperly.

Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
Makefile.in
daemon/remote.c
services/mesh.c
smallapp/unbound-control.c
testcode/fake_event.c
testcode/replay.c
util/netevent.c
util/timehist.c
util/timeval_func.c [new file with mode: 0644]
util/timeval_func.h [new file with mode: 0644]

index 3be1ae8a2853798e18c5451972479778c37f8971..2f16220d3bb7723f3186dd7a15a0865fde1deba5 100644 (file)
@@ -130,7 +130,7 @@ util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
 util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
 util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
 util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
-util/timehist.c util/tube.c util/proxy_protocol.c \
+util/timehist.c util/tube.c util/proxy_protocol.c util/timeval_func.c \
 util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
 validator/autotrust.c validator/val_anchor.c validator/validator.c \
 validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
@@ -152,7 +152,7 @@ autotrust.lo val_anchor.lo rpz.lo proxy_protocol.lo \
 validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
 val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \
 $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
-$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
+$(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo timeval_func.lo
 COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
 outside_network.lo
 COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
@@ -455,6 +455,7 @@ unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnsta
 dynlibmod.lo dynlibdmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h
 cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h
 redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h
+timeval_func.lo timeval_func.o: $(srcdir)/util/timeval_func.c $(srcdir)/util/timeval_func.h
 
 # dnscrypt
 dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@@ -928,7 +929,7 @@ shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/ut
  $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
  $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
  $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h
+ $(srcdir)/util/tube.h $(srcdir)/util/timeval_func.h
 authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
  $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/data/msgparse.h \
@@ -983,7 +984,7 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
  $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
  $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
  $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/dnstap/dnstap.h  $(srcdir)/services/listen_dnsport.h
+ $(srcdir)/dnstap/dnstap.h  $(srcdir)/services/listen_dnsport.h $(srcdir)/util/timeval_func.h
 proxy_protocol.lo proxy_protocol.o: $(srcdir)/util/proxy_protocol.c config.h \
  $(srcdir)/util/proxy_protocol.h $(srcdir)/sldns/sbuffer.h
 net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
@@ -1321,7 +1322,7 @@ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $
 worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/timeval_func.h \
  $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
  $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
@@ -1343,7 +1344,7 @@ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/test
  $(srcdir)/daemon/remote.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c $(srcdir)/daemon/daemon.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+ $(srcdir)/util/alloc.h $(srcdir)/util/timeval_func.h $(srcdir)/services/modstack.h  \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
@@ -1357,7 +1358,7 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
 worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/timeval_func.h \
  $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
  $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
@@ -1409,7 +1410,7 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
  $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
 replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
-  $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
+  $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h $(srcdir)/util/timeval_func.h \
  $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
 fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
  $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
@@ -1417,7 +1418,7 @@ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/t
  $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
  $(srcdir)/util/edns.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h $(srcdir)/util/timeval_func.h \
   $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
  $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
  $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
index 08c50383973d6964a9a1e7692d1fe2c9efbc7626..1d0a587145842109ac78f5142e9bd3cba18ba2c7 100644 (file)
@@ -87,6 +87,7 @@
 #include "sldns/parseutil.h"
 #include "sldns/wire2str.h"
 #include "sldns/sbuffer.h"
+#include "util/timeval_func.h"
 
 #ifdef HAVE_SYS_TYPES_H
 #  include <sys/types.h>
 /** what to put on statistics lines between var and value, ": " or "=" */
 #define SQ "="
 
-/** subtract timers and the values do not overflow or become negative */
-static void
-timeval_subtract(struct timeval* d, const struct timeval* end,
-       const struct timeval* start)
-{
-#ifndef S_SPLINT_S
-       time_t end_usec = end->tv_usec;
-       d->tv_sec = end->tv_sec - start->tv_sec;
-       if(end_usec < start->tv_usec) {
-               end_usec += 1000000;
-               d->tv_sec--;
-       }
-       d->tv_usec = end_usec - start->tv_usec;
-#endif
-}
-
-/** divide sum of timers to get average */
-static void
-timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
-{
-#ifndef S_SPLINT_S
-       size_t leftover;
-       if(d <= 0) {
-               avg->tv_sec = 0;
-               avg->tv_usec = 0;
-               return;
-       }
-       avg->tv_sec = sum->tv_sec / d;
-       avg->tv_usec = sum->tv_usec / d;
-       /* handle fraction from seconds divide */
-       leftover = sum->tv_sec - avg->tv_sec*d;
-       if(leftover <= 0)
-               leftover = 0;
-       avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
-       if(avg->tv_sec < 0)
-               avg->tv_sec = 0;
-       if(avg->tv_usec < 0)
-               avg->tv_usec = 0;
-#endif
-}
-
 static int
 remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
 {
index 035ffa694f8a65098ae1988a432fc18a231f50e6..bff0c03e6f043027149d36173ca7539f86268dac 100644 (file)
 #include "util/data/dname.h"
 #include "respip/respip.h"
 #include "services/listen_dnsport.h"
+#include "util/timeval_func.h"
 
 #ifdef CLIENT_SUBNET
 #include "edns-subnet/subnetmod.h"
 #include "edns-subnet/edns-subnet.h"
 #endif
 
-/** subtract timers and the values do not overflow or become negative */
-static void
-timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start)
-{
-#ifndef S_SPLINT_S
-       time_t end_usec = end->tv_usec;
-       d->tv_sec = end->tv_sec - start->tv_sec;
-       if(end_usec < start->tv_usec) {
-               end_usec += 1000000;
-               d->tv_sec--;
-       }
-       d->tv_usec = end_usec - start->tv_usec;
-#endif
-}
-
-/** add timers and the values do not overflow or become negative */
-static void
-timeval_add(struct timeval* d, const struct timeval* add)
-{
-#ifndef S_SPLINT_S
-       d->tv_sec += add->tv_sec;
-       d->tv_usec += add->tv_usec;
-       if(d->tv_usec >= 1000000 ) {
-               d->tv_usec -= 1000000;
-               d->tv_sec++;
-       }
-#endif
-}
-
-/** divide sum of timers to get average */
-static void
-timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
-{
-#ifndef S_SPLINT_S
-       size_t leftover;
-       if(d <= 0) {
-               avg->tv_sec = 0;
-               avg->tv_usec = 0;
-               return;
-       }
-       avg->tv_sec = sum->tv_sec / d;
-       avg->tv_usec = sum->tv_usec / d;
-       /* handle fraction from seconds divide */
-       leftover = sum->tv_sec - avg->tv_sec*d;
-       if(leftover <= 0)
-               leftover = 0;
-       avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
-       if(avg->tv_sec < 0)
-               avg->tv_sec = 0;
-       if(avg->tv_usec < 0)
-               avg->tv_usec = 0;
-#endif
-}
-
-/** histogram compare of time values */
-static int
-timeval_smaller(const struct timeval* x, const struct timeval* y)
-{
-#ifndef S_SPLINT_S
-       if(x->tv_sec < y->tv_sec)
-               return 1;
-       else if(x->tv_sec == y->tv_sec) {
-               if(x->tv_usec <= y->tv_usec)
-                       return 1;
-               else    return 0;
-       }
-       else    return 0;
-#endif
-}
-
 /**
  * Compare two response-ip client info entries for the purpose of mesh state
  * compare.  It returns 0 if ci_a and ci_b are considered equal; otherwise
index 141bec492ecf007c955060af71fb99ed43724dba..89cb16b9602e89a629d981586a7f49f84f8be9b3 100644 (file)
@@ -59,6 +59,7 @@
 #include "util/locks.h"
 #include "util/net_help.h"
 #include "util/shm_side/shm_main.h"
+#include "util/timeval_func.h"
 #include "daemon/stats.h"
 #include "sldns/wire2str.h"
 #include "sldns/pkthdr.h"
@@ -186,31 +187,6 @@ usage(void)
 #ifdef HAVE_SHMGET
 /** what to put on statistics lines between var and value, ": " or "=" */
 #define SQ "="
-/** divide sum of timers to get average */
-static void
-timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
-{
-#ifndef S_SPLINT_S
-       size_t leftover;
-       if(d <= 0) {
-               avg->tv_sec = 0;
-               avg->tv_usec = 0;
-               return;
-       }
-       avg->tv_sec = sum->tv_sec / d;
-       avg->tv_usec = sum->tv_usec / d;
-       /* handle fraction from seconds divide */
-       leftover = sum->tv_sec - avg->tv_sec*d;
-       if(leftover <= 0)
-               leftover = 0;
-       avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
-       if(avg->tv_sec < 0)
-               avg->tv_sec = 0;
-       if(avg->tv_usec < 0)
-               avg->tv_usec = 0;
-#endif
-}
-
 /** print unsigned long stats value */
 #define PR_UL_NM(str, var) printf("%s."str SQ"%lu\n", nm, (unsigned long)(var));
 #define PR_UL(str, var) printf(str SQ"%lu\n", (unsigned long)(var));
index 618e739d70bdc115c564f3a504e3244216d14531..9d65b3c49ccb1695c7432490e409acba0a4db298 100644 (file)
@@ -65,6 +65,7 @@
 #include "sldns/wire2str.h"
 #include "sldns/str2wire.h"
 #include "daemon/remote.h"
+#include "util/timeval_func.h"
 #include <signal.h>
 struct worker;
 struct daemon_remote;
@@ -95,20 +96,6 @@ struct fake_commpoint {
 /** Global variable: the scenario. Saved here for when event_init is done. */
 static struct replay_scenario* saved_scenario = NULL;
 
-/** add timers and the values do not overflow or become negative */
-static void
-timeval_add(struct timeval* d, const struct timeval* add)
-{
-#ifndef S_SPLINT_S
-       d->tv_sec += add->tv_sec;
-       d->tv_usec += add->tv_usec;
-       if(d->tv_usec >= 1000000) {
-               d->tv_usec -= 1000000;
-               d->tv_sec++;
-       }
-#endif
-}
-
 void
 fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
 {
index 3caf98233399dc25ce772e25bb7b5e2429fc94cf..f896a5512c5d48baa491a9fe98570209a561ddb8 100644 (file)
@@ -51,6 +51,7 @@
 #include "testcode/testpkts.h"
 #include "testcode/fake_event.h"
 #include "sldns/str2wire.h"
+#include "util/timeval_func.h"
 
 /** max length of lines in file */
 #define MAX_LINE_LEN 10240
 static char* macro_expand(rbtree_type* store,
        struct replay_runtime* runtime, char** text);
 
-/** compare of time values */
-static int
-timeval_smaller(const struct timeval* x, const struct timeval* y)
-{
-#ifndef S_SPLINT_S
-       if(x->tv_sec < y->tv_sec)
-               return 1;
-       else if(x->tv_sec == y->tv_sec) {
-               if(x->tv_usec <= y->tv_usec)
-                       return 1;
-               else    return 0;
-       }
-       else    return 0;
-#endif
-}
-
 /** parse keyword in string.
  * @param line: if found, the line is advanced to after the keyword.
  * @param keyword: string.
index a98d12ccc1b3063c2ab9787cbf2b787318ca838b..5558e52ca2e67f0ee0b00be7531f103b628f1a51 100644 (file)
@@ -833,7 +833,6 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
 #ifndef S_SPLINT_S
        struct cmsghdr* cmsg;
 #endif /* S_SPLINT_S */
-
        rep.c = (struct comm_point*)arg;
        log_assert(rep.c->type == comm_udp);
 
@@ -843,6 +842,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
        ub_comm_base_now(rep.c->ev->base);
        for(i=0; i<NUM_UDP_PER_SELECT; i++) {
                sldns_buffer_clear(rep.c->buffer);
+               memset(&rep.c->recv_tv, 0, sizeof(rep.c->recv_tv));
                rep.remote_addrlen = (socklen_t)sizeof(rep.remote_addr);
                log_assert(fd != -1);
                log_assert(sldns_buffer_remaining(rep.c->buffer) > 0);
index 515cf61f3a1b045c0b39e7d7265e93322e59a01e..2063fe80eead8d7ab928e5295161598abbe9d0a8 100644 (file)
@@ -46,6 +46,7 @@
 #include <sys/types.h>
 #include "util/timehist.h"
 #include "util/log.h"
+#include "util/timeval_func.h"
 
 /** special timestwo operation for time values in histogram setup */
 static void
@@ -114,23 +115,6 @@ void timehist_clear(struct timehist* hist)
                hist->buckets[i].count = 0;
 }
 
-/** histogram compare of time values */
-static int
-timeval_smaller(const struct timeval* x, const struct timeval* y)
-{
-#ifndef S_SPLINT_S
-       if(x->tv_sec < y->tv_sec)
-               return 1;
-       else if(x->tv_sec == y->tv_sec) {
-               if(x->tv_usec <= y->tv_usec)
-                       return 1;
-               else    return 0;
-       }
-       else    return 0;
-#endif
-}
-
-
 void timehist_insert(struct timehist* hist, struct timeval* tv)
 {
        size_t i;
diff --git a/util/timeval_func.c b/util/timeval_func.c
new file mode 100644 (file)
index 0000000..83e963d
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * util/timeval_func.c - helpers to work with struct timeval values.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains helpers to manipulate struct timeval values.
+ */
+
+#include "timeval_func.h"
+
+/** subtract timers and the values do not overflow or become negative */
+void
+timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start)
+{
+#ifndef S_SPLINT_S
+       time_t end_usec = end->tv_usec;
+       d->tv_sec = end->tv_sec - start->tv_sec;
+       if(end_usec < start->tv_usec) {
+               end_usec += 1000000;
+               d->tv_sec--;
+       }
+       d->tv_usec = end_usec - start->tv_usec;
+#endif
+}
+
+/** add timers and the values do not overflow or become negative */
+void
+timeval_add(struct timeval* d, const struct timeval* add)
+{
+#ifndef S_SPLINT_S
+       d->tv_sec += add->tv_sec;
+       d->tv_usec += add->tv_usec;
+       if(d->tv_usec >= 1000000 ) {
+               d->tv_usec -= 1000000;
+               d->tv_sec++;
+       }
+#endif
+}
+
+/** divide sum of timers to get average */
+void
+timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
+{
+#ifndef S_SPLINT_S
+       long long leftover;
+       if(d <= 0) {
+               avg->tv_sec = 0;
+               avg->tv_usec = 0;
+               return;
+       }
+       avg->tv_sec = sum->tv_sec / d;
+       avg->tv_usec = sum->tv_usec / d;
+       /* handle fraction from seconds divide */
+       leftover = sum->tv_sec - avg->tv_sec*d;
+       if(leftover <= 0)
+               leftover = 0;
+       avg->tv_usec += (((long long)leftover)*((long long)1000000))/d;
+       if(avg->tv_sec < 0)
+               avg->tv_sec = 0;
+       if(avg->tv_usec < 0)
+               avg->tv_usec = 0;
+#endif
+}
+
+/** histogram compare of time values */
+int
+timeval_smaller(const struct timeval* x, const struct timeval* y)
+{
+#ifndef S_SPLINT_S
+       if(x->tv_sec < y->tv_sec)
+               return 1;
+       else if(x->tv_sec == y->tv_sec) {
+               if(x->tv_usec <= y->tv_usec)
+                       return 1;
+               else    return 0;
+       }
+       else    return 0;
+#endif
+}
diff --git a/util/timeval_func.h b/util/timeval_func.h
new file mode 100644 (file)
index 0000000..afc35c7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * util/timeval)func.h - definitions of helpers for strcut timeval values.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file contains definitions of helpers to manipulate struct timeval
+ * values, implemented in the corresponding C file.
+ */
+#include <sys/time.h>
+
+#ifndef timeval_isset
+#define timeval_isset(tv) ((tv)->tv_sec || (tv)->tv_usec)
+#endif
+#ifndef timeval_clear
+#define timeval_clear(tv) ((tv)->tv_sec = (tv)->tv_usec = 0)
+#endif
+void timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start);
+void timeval_add(struct timeval* d, const struct timeval* add);
+void timeval_divide(struct timeval* avg, const struct timeval* sum, long long d);
+int timeval_smaller(const struct timeval* x, const struct timeval* y);