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 \
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
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 \
$(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 \
$(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 \
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 \
$(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 \
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 \
$(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 \
$(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 \
#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)
{
#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
#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"
#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));
#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;
/** 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)
{
#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.
#ifndef S_SPLINT_S
struct cmsghdr* cmsg;
#endif /* S_SPLINT_S */
-
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
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);
#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
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;
--- /dev/null
+/*
+ * 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
+}
--- /dev/null
+/*
+ * 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);