1 /* $NetBSD: qdisc_jobs.c,v 1.2 2006/10/12 19:59:13 peter Exp $ */
2 /* $KAME: qdisc_jobs.c,v 1.2 2002/10/27 03:19:36 kjc Exp $ */
4 * Copyright (c) 2001-2002, by the Rector and Board of Visitors of the
5 * University of Virginia.
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted provided
10 * that the following conditions are met:
12 * Redistributions of source code must retain the above
13 * copyright notice, this list of conditions and the following
16 * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
21 * Neither the name of the University of Virginia nor the names
22 * of its contributors may be used to endorse or promote products
23 * derived from this software without specific prior written
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
27 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
32 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
37 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
38 * THE POSSIBILITY OF SUCH DAMAGE.
41 * JoBS - altq prototype implementation
43 * Author: Nicolas Christin <nicolas@cs.virginia.edu>
45 * JoBS algorithms originally devised and proposed by
46 * Nicolas Christin and Jorg Liebeherr.
47 * Grateful Acknowledgments to Tarek Abdelzaher for his help and
48 * comments, and to Kenjiro Cho for some helpful advice.
49 * Contributed by the Multimedia Networks Group at the University
52 * http://qosbox.cs.virginia.edu
56 #include <sys/param.h>
57 #include <sys/ioctl.h>
59 #include <sys/socket.h>
61 #include <netinet/in.h>
62 #include <altq/altq.h>
63 #include <altq/altq_jobs.h>
74 #include "quip_client.h"
78 jobs_stat_loop(int fd
, const char *ifname
, int count
, int interval
)
80 struct class_stats stats1
[JOBS_MAXPRI
], stats2
[JOBS_MAXPRI
];
81 char clnames
[JOBS_MAXPRI
][128];
82 struct jobs_class_stats get_stats
;
83 struct class_stats
*sp
, *lp
, *new, *last
, *tmp
;
84 struct timeval cur_time
, last_time
;
90 strlcpy(get_stats
.iface
.jobs_ifname
, ifname
,
91 sizeof(get_stats
.iface
.jobs_ifname
));
95 /* invalidate class handles */
96 for (i
=0; i
<JOBS_MAXPRI
; i
++)
97 last
[i
].class_handle
= JOBS_NULLCLASS_HANDLE
;
100 get_stats
.stats
= new;
101 get_stats
.maxpri
= JOBS_MAXPRI
;
102 if (ioctl(fd
, JOBS_GETSTATS
, &get_stats
) < 0)
103 err(1, "ioctl JOBS_GETSTATS");
105 gettimeofday(&cur_time
, NULL
);
106 sec
= calc_interval(&cur_time
, &last_time
);
108 printf("\n%s:\n", ifname
);
109 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");
111 for (i
= get_stats
.maxpri
; i
>= 0; i
--) {
115 if (sp
->class_handle
== JOBS_NULLCLASS_HANDLE
)
118 if (sp
->class_handle
!= lp
->class_handle
) {
119 quip_chandle2name(ifname
, sp
->class_handle
,
120 clnames
[i
], sizeof(clnames
[0]));
124 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",
126 (sp
->rout
.packets
== 0)?
127 -1.:(double)sp
->avgdel
/(double)sp
->rout
.packets
,
128 (i
> 0)?((sp
->rout
.packets
> 0 && (&new[i
-1])->rout
.packets
> 0)?
129 (double)(sp
->avgdel
*(&new[i
-1])->rout
.packets
)/((double)sp
->rout
.packets
*(&new[i
-1])->avgdel
):0):-1.0,
130 (sp
->arrival
.packets
== 0)?
131 0:(double)100.*sp
->adc_violations
/(double)sp
->arrival
.packets
,
132 (sp
->arrivalbusy
.bytes
== 0)?
133 0:(double)(100.*sp
->dropcnt
.bytes
/(double)(sp
->arrivalbusy
.bytes
)),
135 (sp
->arrivalbusy
.bytes
== 0 || (&new[i
-1])->dropcnt
.bytes
== 0)?
136 0:(double)(sp
->dropcnt
.bytes
*(&new[i
-1])->arrivalbusy
.bytes
)
137 /(double)(sp
->arrivalbusy
.bytes
*(&new[i
-1])->dropcnt
.bytes
)):-1.0,
138 (sp
->rout
.bytes
> 0)?
139 (double)calc_rate(sp
->rout
.bytes
,
141 (sp
->arrival
.bytes
-lp
->arrival
.bytes
> 0)?
142 (double)calc_rate(sp
->arrival
.bytes
-lp
->arrival
.bytes
,
144 (ull
)sp
->bc_cycles_enqueue
,
145 (sp
->total_enqueued
== 0)?
146 -1:(double)sp
->avg_cycles_enqueue
/sp
->total_enqueued
,
147 (sp
->total_enqueued
== 0)?
149 sqrt((double)((u_int
)((sp
->avg_cycles2_enqueue
/sp
->total_enqueued
)
150 -(sp
->avg_cycles_enqueue
/sp
->total_enqueued
*sp
->avg_cycles_enqueue
/sp
->total_enqueued
)))),
151 (ull
)sp
->wc_cycles_enqueue
,
152 (ull
)sp
->bc_cycles_dequeue
,
153 (sp
->total_dequeued
== 0)?
154 -1:(double)sp
->avg_cycles_dequeue
/sp
->total_dequeued
,
155 (sp
->total_dequeued
== 0)?
157 sqrt((double)((u_int
)((sp
->avg_cycles2_dequeue
/sp
->total_dequeued
)
158 -(sp
->avg_cycles_dequeue
/sp
->total_dequeued
*sp
->avg_cycles_dequeue
/sp
->total_dequeued
)))),
159 (ull
)sp
->wc_cycles_dequeue
,
160 (u_int
)sp
->total_enqueued
,
161 (u_int
)sp
->total_dequeued
165 /* swap the buffer pointers */
170 last_time
= cur_time
;
172 if (count
!= 0 && --cnt
== 0)
175 /* wait for alarm signal */
176 if (sigprocmask(SIG_BLOCK
, NULL
, &omask
) == 0)