mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Histogram
git-svn-id: file:///svn/unbound/trunk@428 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
959088280f
commit
6907d9a989
5 changed files with 286 additions and 3 deletions
|
|
@ -7,6 +7,7 @@
|
||||||
This means that unbound tried the host for retries up to 120 secs.
|
This means that unbound tried the host for retries up to 120 secs.
|
||||||
The rto value will time out after host-ttl seconds from the cache.
|
The rto value will time out after host-ttl seconds from the cache.
|
||||||
This keeps such unresolvable queries from taking up resources.
|
This keeps such unresolvable queries from taking up resources.
|
||||||
|
- utility for keeping histogram.
|
||||||
|
|
||||||
26 June 2007: Wouter
|
26 June 2007: Wouter
|
||||||
- mesh is called by worker, and iterator uses it.
|
- mesh is called by worker, and iterator uses it.
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@
|
||||||
#include "util/module.h"
|
#include "util/module.h"
|
||||||
#include "util/region-allocator.h"
|
#include "util/region-allocator.h"
|
||||||
#include "util/data/msgencode.h"
|
#include "util/data/msgencode.h"
|
||||||
|
#include "util/timehist.h"
|
||||||
|
|
||||||
/** compare two mesh_states */
|
/** compare two mesh_states */
|
||||||
static int
|
static int
|
||||||
|
|
@ -89,6 +90,12 @@ mesh_create(int num_modules, struct module_func_block** modfunc,
|
||||||
log_err("mesh area alloc: out of memory");
|
log_err("mesh area alloc: out of memory");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
mesh->histogram = timehist_setup();
|
||||||
|
if(!mesh->histogram) {
|
||||||
|
free(mesh);
|
||||||
|
log_err("mesh area alloc: out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
mesh->num_modules = num_modules;
|
mesh->num_modules = num_modules;
|
||||||
mesh->modfunc = modfunc;
|
mesh->modfunc = modfunc;
|
||||||
mesh->env = env;
|
mesh->env = env;
|
||||||
|
|
@ -115,6 +122,7 @@ mesh_delete(struct mesh_area* mesh)
|
||||||
return;
|
return;
|
||||||
/* free all query states */
|
/* free all query states */
|
||||||
traverse_postorder(&mesh->all, &mesh_delete_helper, NULL);
|
traverse_postorder(&mesh->all, &mesh_delete_helper, NULL);
|
||||||
|
timehist_delete(mesh->histogram);
|
||||||
free(mesh);
|
free(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -444,6 +452,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||||
(int)duration.tv_sec, (int)duration.tv_usec);
|
(int)duration.tv_sec, (int)duration.tv_usec);
|
||||||
m->s.env->mesh->replies_sent++;
|
m->s.env->mesh->replies_sent++;
|
||||||
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
|
timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
|
||||||
|
timehist_insert(m->s.env->mesh->histogram, &duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -543,13 +552,14 @@ void mesh_run(struct mesh_area* mesh, struct mesh_state* mstate,
|
||||||
(void)rbtree_delete(&mesh->run, mstate);
|
(void)rbtree_delete(&mesh->run, mstate);
|
||||||
} else mstate = NULL;
|
} else mstate = NULL;
|
||||||
}
|
}
|
||||||
mesh_stats(mesh, "mesh_run: end");
|
if(verbosity >= VERB_ALGO)
|
||||||
|
mesh_stats(mesh, "mesh_run: end");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mesh_stats(struct mesh_area* mesh, const char* str)
|
mesh_stats(struct mesh_area* mesh, const char* str)
|
||||||
{
|
{
|
||||||
verbose(VERB_ALGO, "%s %u states (%u with reply, %u detached), "
|
log_info("%s %u states (%u with reply, %u detached), "
|
||||||
"%u waiting replies", str, (unsigned)mesh->all.count,
|
"%u waiting replies", str, (unsigned)mesh->all.count,
|
||||||
(unsigned)mesh->num_reply_states,
|
(unsigned)mesh->num_reply_states,
|
||||||
(unsigned)mesh->num_detached_states,
|
(unsigned)mesh->num_detached_states,
|
||||||
|
|
@ -558,8 +568,10 @@ mesh_stats(struct mesh_area* mesh, const char* str)
|
||||||
struct timeval avg;
|
struct timeval avg;
|
||||||
timeval_divide(&avg, &mesh->replies_sum_wait,
|
timeval_divide(&avg, &mesh->replies_sum_wait,
|
||||||
mesh->replies_sent);
|
mesh->replies_sent);
|
||||||
verbose(VERB_ALGO, "sent %u replies, with average wait "
|
log_info("sent %u replies, with average wait "
|
||||||
"of %d.%6.6d sec", (unsigned)mesh->replies_sent,
|
"of %d.%6.6d sec", (unsigned)mesh->replies_sent,
|
||||||
(int)avg.tv_sec, (int)avg.tv_usec);
|
(int)avg.tv_sec, (int)avg.tv_usec);
|
||||||
|
log_info("histogram of reply wait times");
|
||||||
|
timehist_log(mesh->histogram);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ struct mesh_reply;
|
||||||
struct query_info;
|
struct query_info;
|
||||||
struct reply_info;
|
struct reply_info;
|
||||||
struct outbound_entry;
|
struct outbound_entry;
|
||||||
|
struct timehist;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mesh of query states
|
* Mesh of query states
|
||||||
|
|
@ -87,6 +88,8 @@ struct mesh_area {
|
||||||
size_t replies_sent;
|
size_t replies_sent;
|
||||||
/** sum of waiting times for the replies */
|
/** sum of waiting times for the replies */
|
||||||
struct timeval replies_sum_wait;
|
struct timeval replies_sum_wait;
|
||||||
|
/** histogram of time values */
|
||||||
|
struct timehist* histogram;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
169
util/timehist.c
Normal file
169
util/timehist.c
Normal file
|
|
@ -0,0 +1,169 @@
|
||||||
|
/*
|
||||||
|
* util/timehist.c - make histogram of time 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 REGENTS 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 functions to make a histogram of time values.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "util/timehist.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
/** special timestwo operation for time values in histogram setup */
|
||||||
|
static void
|
||||||
|
timestwo(struct timeval* v)
|
||||||
|
{
|
||||||
|
#ifndef S_SPLINT_S
|
||||||
|
if(v->tv_sec == 0 && v->tv_usec == 0) {
|
||||||
|
v->tv_usec = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
v->tv_sec *= 2;
|
||||||
|
v->tv_usec *= 2;
|
||||||
|
if(v->tv_usec == 1024*1024) {
|
||||||
|
/* nice values and easy to compute */
|
||||||
|
v->tv_sec = 1;
|
||||||
|
v->tv_usec = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/** do setup exponentially */
|
||||||
|
static void
|
||||||
|
dosetup(struct timehist* hist)
|
||||||
|
{
|
||||||
|
struct timeval last;
|
||||||
|
size_t i;
|
||||||
|
memset(&last, 0, sizeof(last));
|
||||||
|
for(i=0; i<hist->num; i++) {
|
||||||
|
hist->buckets[i].lower = last;
|
||||||
|
timestwo(&last);
|
||||||
|
hist->buckets[i].upper = last;
|
||||||
|
hist->buckets[i].count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct timehist* timehist_setup()
|
||||||
|
{
|
||||||
|
struct timehist* hist = (struct timehist*)calloc(1,
|
||||||
|
sizeof(struct timehist));
|
||||||
|
if(!hist)
|
||||||
|
return NULL;
|
||||||
|
hist->num = 40;
|
||||||
|
hist->buckets = (struct th_buck*)calloc(hist->num,
|
||||||
|
sizeof(struct th_buck));
|
||||||
|
if(!hist->buckets) {
|
||||||
|
free(hist);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* setup the buckets */
|
||||||
|
dosetup(hist);
|
||||||
|
return hist;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timehist_delete(struct timehist* hist)
|
||||||
|
{
|
||||||
|
if(!hist)
|
||||||
|
return;
|
||||||
|
free(hist->buckets);
|
||||||
|
free(hist);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** histogram compare of time values */
|
||||||
|
static int
|
||||||
|
timeval_smaller(struct timeval* x, 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;
|
||||||
|
for(i=0; i<hist->num; i++) {
|
||||||
|
if(timeval_smaller(tv, &hist->buckets[i].upper)) {
|
||||||
|
hist->buckets[i].count++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* dump in last bucket */
|
||||||
|
hist->buckets[hist->num-1].count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void timehist_print(struct timehist* hist)
|
||||||
|
{
|
||||||
|
#ifndef S_SPLINT_S
|
||||||
|
size_t i;
|
||||||
|
for(i=0; i<hist->num; i++) {
|
||||||
|
if(hist->buckets[i].count != 0) {
|
||||||
|
printf("%4d.%6.6d %4d.%6.6d %u\n",
|
||||||
|
(int)hist->buckets[i].lower.tv_sec,
|
||||||
|
(int)hist->buckets[i].lower.tv_usec,
|
||||||
|
(int)hist->buckets[i].upper.tv_sec,
|
||||||
|
(int)hist->buckets[i].upper.tv_usec,
|
||||||
|
(unsigned)hist->buckets[i].count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void timehist_log(struct timehist* hist)
|
||||||
|
{
|
||||||
|
#ifndef S_SPLINT_S
|
||||||
|
size_t i;
|
||||||
|
/* 0000.000000 0000.000000 0 */
|
||||||
|
log_info("lower(secs) upper(secs) replycount");
|
||||||
|
for(i=0; i<hist->num; i++) {
|
||||||
|
if(hist->buckets[i].count != 0) {
|
||||||
|
log_info("%4d.%6.6d %4d.%6.6d %u",
|
||||||
|
(int)hist->buckets[i].lower.tv_sec,
|
||||||
|
(int)hist->buckets[i].lower.tv_usec,
|
||||||
|
(int)hist->buckets[i].upper.tv_sec,
|
||||||
|
(int)hist->buckets[i].upper.tv_usec,
|
||||||
|
(unsigned)hist->buckets[i].count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
98
util/timehist.h
Normal file
98
util/timehist.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* util/timehist.h - make histogram of time 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 REGENTS 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 functions to make a histogram of time values.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTIL_TIMEHIST_H
|
||||||
|
#define UTIL_TIMEHIST_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bucket of time history information
|
||||||
|
*/
|
||||||
|
struct th_buck {
|
||||||
|
/** lower bound */
|
||||||
|
struct timeval lower;
|
||||||
|
/** upper bound */
|
||||||
|
struct timeval upper;
|
||||||
|
/** number of items */
|
||||||
|
size_t count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keep histogram of time values.
|
||||||
|
*/
|
||||||
|
struct timehist {
|
||||||
|
/** number of buckets */
|
||||||
|
size_t num;
|
||||||
|
/** bucket array */
|
||||||
|
struct th_buck* buckets;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup a histogram, default
|
||||||
|
* @return histogram or NULL on malloc failure.
|
||||||
|
*/
|
||||||
|
struct timehist* timehist_setup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete histogram
|
||||||
|
* @param hist: to delete
|
||||||
|
*/
|
||||||
|
void timehist_delete(struct timehist* hist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add time value to histogram.
|
||||||
|
* @param hist: histogram
|
||||||
|
* @param tv: time value
|
||||||
|
*/
|
||||||
|
void timehist_insert(struct timehist* hist, struct timeval* tv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Printout histogram
|
||||||
|
* @param hist: histogram
|
||||||
|
*/
|
||||||
|
void timehist_print(struct timehist* hist);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log histogram, print it to the logfile.
|
||||||
|
* @param hist: histogram
|
||||||
|
*/
|
||||||
|
void timehist_log(struct timehist* hist);
|
||||||
|
|
||||||
|
#endif /* UTIL_TIMEHIST_H */
|
||||||
Loading…
Reference in a new issue