diff options
author | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-11-05 16:28:09 +0100 |
---|---|---|
committer | Alberto Gonzalez Iniesta <agi@inittab.org> | 2012-11-05 16:28:09 +0100 |
commit | 8dd0350e1607aa30f7a043c8d5ec7a7eeb874115 (patch) | |
tree | 566d0620eb693320cb121dfd93a5675fa704a30b /perf.c | |
parent | 349cfa7acb95abe865209a28e417ec74b56f9bba (diff) |
Imported Upstream version 2.3_rc1
Diffstat (limited to 'perf.c')
-rw-r--r-- | perf.c | 293 |
1 files changed, 0 insertions, 293 deletions
@@ -1,293 +0,0 @@ -/* - * OpenVPN -- An application to securely tunnel IP networks - * over a single TCP/UDP port, with support for SSL/TLS-based - * session authentication and key exchange, - * packet encryption, packet authentication, and - * packet compression. - * - * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> - * - * 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 (see the file COPYING included with this - * distribution); if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "syshead.h" - -#include "perf.h" - -#ifdef ENABLE_PERFORMANCE_METRICS - -#include "error.h" -#include "otime.h" - -#include "memdbg.h" - -static const char *metric_names[] = { - "PERF_BIO_READ_PLAINTEXT", - "PERF_BIO_WRITE_PLAINTEXT", - "PERF_BIO_READ_CIPHERTEXT", - "PERF_BIO_WRITE_CIPHERTEXT", - "PERF_TLS_MULTI_PROCESS", - "PERF_IO_WAIT", - "PERF_EVENT_LOOP", - "PERF_MULTI_CREATE_INSTANCE", - "PERF_MULTI_CLOSE_INSTANCE", - "PERF_MULTI_SHOW_STATS", - "PERF_MULTI_BCAST", - "PERF_MULTI_MCAST", - "PERF_SCRIPT", - "PERF_READ_IN_LINK", - "PERF_PROC_IN_LINK", - "PERF_READ_IN_TUN", - "PERF_PROC_IN_TUN", - "PERF_PROC_OUT_LINK", - "PERF_PROC_OUT_TUN", - "PERF_PROC_OUT_TUN_MTCP" -}; - -struct perf -{ -# define PS_INITIAL 0 -# define PS_METER_RUNNING 1 -# define PS_METER_INTERRUPTED 2 - int state; - - struct timeval start; - double sofar; - double sum; - double max; - double count; -}; - -struct perf_set -{ - int stack_len; - int stack[STACK_N]; - struct perf perf[PERF_N]; -}; - -static struct perf_set perf_set; - -static void perf_print_state (int lev); - -static inline int -get_stack_index (int sdelta) -{ - const int sindex = perf_set.stack_len + sdelta; - if (sindex >= 0 && sindex < STACK_N) - return sindex; - else - return -1; -} - -static int -get_perf_index (int sdelta) -{ - const int sindex = get_stack_index (sdelta); - if (sindex >= 0) - { - const int pindex = perf_set.stack[sindex]; - if (pindex >= 0 && pindex < PERF_N) - return pindex; - else - return -1; - } - else - return -1; -} - -static struct perf * -get_perf (int sdelta) -{ - const int pindex = get_perf_index (sdelta); - if (pindex >= 0) - return &perf_set.perf[pindex]; - else - return NULL; -} - -static void -push_perf_index (int pindex) -{ - const int sindex = get_stack_index (0); - const int newlen = get_stack_index (1); - if (sindex >= 0 && newlen >= 0 - && pindex >= 0 && pindex < PERF_N) - { - int i; - for (i = 0; i < sindex; ++i) - if (perf_set.stack[i] == pindex) - { - perf_print_state (M_INFO); - msg (M_FATAL, "PERF: push_perf_index %s failed", - metric_names [pindex]); - } - - perf_set.stack[sindex] = pindex; - perf_set.stack_len = newlen; - } - else - msg (M_FATAL, "PERF: push_perf_index: stack push error"); -} - -static void -pop_perf_index (void) -{ - const int newlen = get_stack_index (-1); - if (newlen >= 0) - { - perf_set.stack_len = newlen; - } - else - msg (M_FATAL, "PERF: pop_perf_index: stack pop error"); -} - -static void -state_must_be (const struct perf *p, const int wanted) -{ - if (p->state != wanted) - msg (M_FATAL, "PERF: bad state actual=%d wanted=%d", - p->state, - wanted); -} - -static void -update_sofar (struct perf *p) -{ - struct timeval current; - ASSERT (!gettimeofday (¤t, NULL)); - p->sofar += (double) tv_subtract (¤t, &p->start, 600) / 1000000.0; - tv_clear (&p->start); -} - -static void -perf_start (struct perf *p) -{ - state_must_be (p, PS_INITIAL); - ASSERT (!gettimeofday (&p->start, NULL)); - p->sofar = 0.0; - p->state = PS_METER_RUNNING; -} - -static void -perf_stop (struct perf *p) -{ - state_must_be (p, PS_METER_RUNNING); - update_sofar (p); - p->sum += p->sofar; - if (p->sofar > p->max) - p->max = p->sofar; - p->count += 1.0; - p->sofar = 0.0; - p->state = PS_INITIAL; -} - -static void -perf_interrupt (struct perf *p) -{ - state_must_be (p, PS_METER_RUNNING); - update_sofar (p); - p->state = PS_METER_INTERRUPTED; -} - -static void -perf_resume (struct perf *p) -{ - state_must_be (p, PS_METER_INTERRUPTED); - ASSERT (!gettimeofday (&p->start, NULL)); - p->state = PS_METER_RUNNING; -} - -void -perf_push (int type) -{ - struct perf *prev; - struct perf *cur; - - ASSERT (SIZE(metric_names) == PERF_N); - push_perf_index (type); - - prev = get_perf (-2); - cur = get_perf (-1); - - ASSERT (cur); - - if (prev) - perf_interrupt (prev); - perf_start (cur); -} - -void -perf_pop (void) -{ - struct perf *prev; - struct perf *cur; - - prev = get_perf (-2); - cur = get_perf (-1); - - ASSERT (cur); - perf_stop (cur); - - if (prev) - perf_resume (prev); - - pop_perf_index (); -} - -void -perf_output_results (void) -{ - int i; - msg (M_INFO, "LATENCY PROFILE (mean and max are in milliseconds)"); - for (i = 0; i < PERF_N; ++i) - { - struct perf *p = &perf_set.perf[i]; - if (p->count > 0.0) - { - const double mean = p->sum / p->count; - msg (M_INFO, "%s n=%.0f mean=%.3f max=%.3f", metric_names[i], p->count, mean*1000.0, p->max*1000.0); - } - } -} - -static void -perf_print_state (int lev) -{ - struct gc_arena gc = gc_new (); - int i; - msg (lev, "PERF STATE"); - msg (lev, "Stack:"); - for (i = 0; i < perf_set.stack_len; ++i) - { - const int j = perf_set.stack[i]; - const struct perf *p = &perf_set.perf[j]; - msg (lev, "[%d] %s state=%d start=%s sofar=%f sum=%f max=%f count=%f", - i, - metric_names[j], - p->state, - tv_string (&p->start, &gc), - p->sofar, - p->sum, - p->max, - p->count); - } - gc_free (&gc); -} - -#else -#ifdef _MSC_VER /* Dummy function needed to avoid empty file compiler warning in Microsoft VC */ -static void dummy(void) {} -#endif -#endif |