Home | History | Annotate | Line # | Download | only in altqstat
      1  1.3  peter /*	$NetBSD: qdisc_jobs.c,v 1.3 2006/10/28 11:43:02 peter Exp $	*/
      2  1.2  peter /*	$KAME: qdisc_jobs.c,v 1.2 2002/10/27 03:19:36 kjc Exp $	*/
      3  1.2  peter /*
      4  1.2  peter  * Copyright (c) 2001-2002, by the Rector and Board of Visitors of the
      5  1.2  peter  * University of Virginia.
      6  1.2  peter  * All rights reserved.
      7  1.2  peter  *
      8  1.2  peter  * Redistribution and use in source and binary forms,
      9  1.2  peter  * with or without modification, are permitted provided
     10  1.2  peter  * that the following conditions are met:
     11  1.2  peter  *
     12  1.2  peter  * Redistributions of source code must retain the above
     13  1.2  peter  * copyright notice, this list of conditions and the following
     14  1.2  peter  * disclaimer.
     15  1.2  peter  *
     16  1.2  peter  * Redistributions in binary form must reproduce the above
     17  1.2  peter  * copyright notice, this list of conditions and the following
     18  1.2  peter  * disclaimer in the documentation and/or other materials provided
     19  1.2  peter  * with the distribution.
     20  1.2  peter  *
     21  1.2  peter  * Neither the name of the University of Virginia nor the names
     22  1.2  peter  * of its contributors may be used to endorse or promote products
     23  1.2  peter  * derived from this software without specific prior written
     24  1.2  peter  * permission.
     25  1.2  peter  *
     26  1.2  peter  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
     27  1.2  peter  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
     28  1.2  peter  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     29  1.2  peter  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     30  1.2  peter  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
     31  1.2  peter  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     32  1.2  peter  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     33  1.2  peter  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     34  1.2  peter  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     35  1.2  peter  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     36  1.2  peter  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     37  1.2  peter  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     38  1.2  peter  * THE POSSIBILITY OF SUCH DAMAGE.
     39  1.2  peter  */
     40  1.2  peter /*
     41  1.2  peter  * JoBS - altq prototype implementation
     42  1.2  peter  *
     43  1.2  peter  * Author: Nicolas Christin <nicolas (at) cs.virginia.edu>
     44  1.2  peter  *
     45  1.2  peter  * JoBS algorithms originally devised and proposed by
     46  1.2  peter  * Nicolas Christin and Jorg Liebeherr.
     47  1.2  peter  * Grateful Acknowledgments to Tarek Abdelzaher for his help and
     48  1.2  peter  * comments, and to Kenjiro Cho for some helpful advice.
     49  1.2  peter  * Contributed by the Multimedia Networks Group at the University
     50  1.2  peter  * of Virginia.
     51  1.2  peter  *
     52  1.2  peter  * http://qosbox.cs.virginia.edu
     53  1.2  peter  *
     54  1.2  peter  */
     55  1.2  peter 
     56  1.2  peter #include <sys/param.h>
     57  1.2  peter #include <sys/ioctl.h>
     58  1.2  peter #include <sys/time.h>
     59  1.2  peter #include <sys/socket.h>
     60  1.2  peter #include <net/if.h>
     61  1.2  peter #include <netinet/in.h>
     62  1.2  peter #include <altq/altq.h>
     63  1.2  peter #include <altq/altq_jobs.h>
     64  1.2  peter 
     65  1.2  peter #include <stdio.h>
     66  1.2  peter #include <stdlib.h>
     67  1.2  peter #include <unistd.h>
     68  1.2  peter #include <string.h>
     69  1.2  peter #include <signal.h>
     70  1.2  peter #include <math.h>
     71  1.2  peter #include <errno.h>
     72  1.2  peter #include <err.h>
     73  1.2  peter 
     74  1.2  peter #include "quip_client.h"
     75  1.2  peter #include "altqstat.h"
     76  1.2  peter 
     77  1.2  peter void
     78  1.2  peter jobs_stat_loop(int fd, const char *ifname, int count, int interval)
     79  1.2  peter {
     80  1.2  peter 	struct class_stats	stats1[JOBS_MAXPRI], stats2[JOBS_MAXPRI];
     81  1.2  peter 	char			clnames[JOBS_MAXPRI][128];
     82  1.2  peter 	struct jobs_class_stats	get_stats;
     83  1.2  peter 	struct class_stats	*sp, *lp, *new, *last, *tmp;
     84  1.2  peter 	struct timeval		cur_time, last_time;
     85  1.2  peter 	int			i;
     86  1.2  peter 	double			sec;
     87  1.2  peter 	int			cnt = count;
     88  1.2  peter 	sigset_t		omask;
     89  1.2  peter 
     90  1.2  peter 	strlcpy(get_stats.iface.jobs_ifname, ifname,
     91  1.2  peter 		sizeof(get_stats.iface.jobs_ifname));
     92  1.2  peter 	new = &stats1[0];
     93  1.2  peter 	last = &stats2[0];
     94  1.2  peter 
     95  1.2  peter 	/* invalidate class handles */
     96  1.2  peter 	for (i=0; i<JOBS_MAXPRI; i++)
     97  1.2  peter 		last[i].class_handle = JOBS_NULLCLASS_HANDLE;
     98  1.2  peter 
     99  1.3  peter 	for (;;) {
    100  1.2  peter 		get_stats.stats = new;
    101  1.2  peter 		get_stats.maxpri = JOBS_MAXPRI;
    102  1.2  peter 		if (ioctl(fd, JOBS_GETSTATS, &get_stats) < 0)
    103  1.2  peter 			err(1, "ioctl JOBS_GETSTATS");
    104  1.2  peter 
    105  1.2  peter 		gettimeofday(&cur_time, NULL);
    106  1.2  peter 		sec = calc_interval(&cur_time, &last_time);
    107  1.2  peter 
    108  1.2  peter 		printf("\n%s:\n", ifname);
    109  1.2  peter 		printf("pri\tdel\trdc\tviol\tp_i\trlc\tthru\toff_ld\tbc_e\tavg_e\tstdev_e\twc_e\tbc_d\tavg_d\tstdev_d\twc_d\tnr_en\tnr_de\n");
    110  1.2  peter 
    111  1.2  peter 		for (i = get_stats.maxpri; i >= 0; i--) {
    112  1.2  peter 			sp = &new[i];
    113  1.2  peter 			lp = &last[i];
    114  1.2  peter 
    115  1.2  peter 			if (sp->class_handle == JOBS_NULLCLASS_HANDLE)
    116  1.2  peter 				continue;
    117  1.2  peter 
    118  1.2  peter 			if (sp->class_handle != lp->class_handle) {
    119  1.2  peter 				quip_chandle2name(ifname, sp->class_handle,
    120  1.2  peter 				clnames[i], sizeof(clnames[0]));
    121  1.2  peter 				continue;
    122  1.2  peter 			}
    123  1.2  peter 
    124  1.2  peter 			printf("%d\t%.0f\t%.2f\t%.3f\t%.2f\t%.2f\t%.3f\t%.2f\t%llu\t%.0f\t%.0f\t%llu\t%llu\t%.0f\t%.0f\t%llu\t%u\t%u\n",
    125  1.2  peter 			       i,
    126  1.2  peter 			       (sp->rout.packets == 0)?
    127  1.2  peter 			       -1.:(double)sp->avgdel/(double)sp->rout.packets,
    128  1.2  peter 			       (i > 0)?((sp->rout.packets > 0 && (&new[i-1])->rout.packets > 0)?
    129  1.2  peter 					(double)(sp->avgdel*(&new[i-1])->rout.packets)/((double)sp->rout.packets*(&new[i-1])->avgdel):0):-1.0,
    130  1.2  peter 			       (sp->arrival.packets == 0)?
    131  1.2  peter 			       0:(double)100.*sp->adc_violations/(double)sp->arrival.packets,
    132  1.2  peter 			       (sp->arrivalbusy.bytes == 0)?
    133  1.2  peter 			       0:(double)(100.*sp->dropcnt.bytes/(double)(sp->arrivalbusy.bytes)),
    134  1.2  peter 			       (i > 0)?(
    135  1.2  peter 					(sp->arrivalbusy.bytes == 0 || (&new[i-1])->dropcnt.bytes == 0)?
    136  1.2  peter 					0:(double)(sp->dropcnt.bytes*(&new[i-1])->arrivalbusy.bytes)
    137  1.2  peter 					/(double)(sp->arrivalbusy.bytes*(&new[i-1])->dropcnt.bytes)):-1.0,
    138  1.2  peter 			       (sp->rout.bytes > 0)?
    139  1.2  peter 			       (double)calc_rate(sp->rout.bytes,
    140  1.2  peter 						 0, sec)/1000000.:0,
    141  1.2  peter 			       (sp->arrival.bytes-lp->arrival.bytes > 0)?
    142  1.2  peter 			       (double)calc_rate(sp->arrival.bytes-lp->arrival.bytes,
    143  1.2  peter 						 0, sec)/1000000.:0,
    144  1.2  peter 			       (ull)sp->bc_cycles_enqueue,
    145  1.2  peter 			       (sp->total_enqueued == 0)?
    146  1.2  peter 			       -1:(double)sp->avg_cycles_enqueue/sp->total_enqueued,
    147  1.2  peter 			       (sp->total_enqueued == 0)?
    148  1.2  peter 			       -1.:
    149  1.2  peter 			       sqrt((double)((u_int)((sp->avg_cycles2_enqueue/sp->total_enqueued)
    150  1.2  peter 						     -(sp->avg_cycles_enqueue/sp->total_enqueued*sp->avg_cycles_enqueue/sp->total_enqueued)))),
    151  1.2  peter 			       (ull)sp->wc_cycles_enqueue,
    152  1.2  peter 			       (ull)sp->bc_cycles_dequeue,
    153  1.2  peter 			       (sp->total_dequeued == 0)?
    154  1.2  peter 			       -1:(double)sp->avg_cycles_dequeue/sp->total_dequeued,
    155  1.2  peter 			       (sp->total_dequeued == 0)?
    156  1.2  peter 			       -1.:
    157  1.2  peter 			       sqrt((double)((u_int)((sp->avg_cycles2_dequeue/sp->total_dequeued)
    158  1.2  peter 						     -(sp->avg_cycles_dequeue/sp->total_dequeued*sp->avg_cycles_dequeue/sp->total_dequeued)))),
    159  1.2  peter 			       (ull)sp->wc_cycles_dequeue,
    160  1.2  peter 			       (u_int)sp->total_enqueued,
    161  1.2  peter 			       (u_int)sp->total_dequeued
    162  1.2  peter 			       );
    163  1.2  peter 		}
    164  1.2  peter 
    165  1.2  peter 		/* swap the buffer pointers */
    166  1.2  peter 		tmp = last;
    167  1.2  peter 		last = new;
    168  1.2  peter 		new = tmp;
    169  1.2  peter 
    170  1.2  peter 		last_time = cur_time;
    171  1.2  peter 
    172  1.3  peter 		if (count != 0 && --cnt == 0)
    173  1.3  peter 			break;
    174  1.3  peter 
    175  1.2  peter 		/* wait for alarm signal */
    176  1.2  peter 		if (sigprocmask(SIG_BLOCK, NULL, &omask) == 0)
    177  1.2  peter 			sigsuspend(&omask);
    178  1.2  peter 	}
    179  1.2  peter }
    180