summaryrefslogtreecommitdiffstats
path: root/ui/io_graph_item.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-09-19 04:14:26 +0000
commitc4e8a3222648fcf22ca207f1815ebbf7cd144eeb (patch)
tree93d5c6aa93d9987680dd1adad5685e2ad698f223 /ui/io_graph_item.h
parentAdding upstream version 4.2.6. (diff)
downloadwireshark-upstream.tar.xz
wireshark-upstream.zip
Adding upstream version 4.4.0.upstream/4.4.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/io_graph_item.h')
-rw-r--r--ui/io_graph_item.h287
1 files changed, 158 insertions, 129 deletions
diff --git a/ui/io_graph_item.h b/ui/io_graph_item.h
index 1323691b..d2475e06 100644
--- a/ui/io_graph_item.h
+++ b/ui/io_graph_item.h
@@ -17,6 +17,8 @@
#include "cfile.h"
#include <wsutil/ws_assert.h>
+#include <epan/epan_dissect.h>
+
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -32,33 +34,42 @@ typedef enum {
IOG_ITEM_UNIT_CALC_MAX,
IOG_ITEM_UNIT_CALC_MIN,
IOG_ITEM_UNIT_CALC_AVERAGE,
+ IOG_ITEM_UNIT_CALC_THROUGHPUT,
IOG_ITEM_UNIT_CALC_LOAD,
IOG_ITEM_UNIT_LAST = IOG_ITEM_UNIT_CALC_LOAD,
NUM_IOG_ITEM_UNITS
} io_graph_item_unit_t;
typedef struct _io_graph_item_t {
- guint32 frames; /* always calculated, will hold number of frames*/
- guint64 bytes; /* always calculated, will hold number of bytes*/
- guint64 fields;
- gint64 int_max;
- gint64 int_min;
- gint64 int_tot;
- /* XXX - Why do we always use 64-bit ints but split floats between
- * gfloat and gdouble?
+ uint32_t frames; /* always calculated, will hold number of frames*/
+ uint64_t bytes; /* always calculated, will hold number of bytes*/
+ uint64_t fields;
+ /* We use a double for totals because of overflow. For min and max,
+ * unsigned 64 bit integers larger than 2^53 cannot all be represented
+ * in a double, and this is useful for determining the frame with the
+ * min or max value, even though for plotting it will be converted to a
+ * double.
*/
- gfloat float_max;
- gfloat float_min;
- gfloat float_tot;
- gdouble double_max;
- gdouble double_min;
- gdouble double_tot;
- nstime_t time_max;
- nstime_t time_min;
- nstime_t time_tot;
- guint32 first_frame_in_invl;
- guint32 extreme_frame_in_invl; /* frame with min/max value */
- guint32 last_frame_in_invl;
+ union {
+ nstime_t time_max;
+ double double_max;
+ int64_t int_max;
+ uint64_t uint_max;
+ };
+ union {
+ nstime_t time_min;
+ double double_min;
+ int64_t int_min;
+ uint64_t uint_min;
+ };
+ union {
+ nstime_t time_tot;
+ double double_tot;
+ };
+ uint32_t first_frame_in_invl;
+ uint32_t min_frame_in_invl;
+ uint32_t max_frame_in_invl;
+ uint32_t last_frame_in_invl;
} io_graph_item_t;
/** Reset (zero) an io_graph_item_t.
@@ -67,9 +78,9 @@ typedef struct _io_graph_item_t {
* @param count [in] The number of items in the array.
*/
static inline void
-reset_io_graph_items(io_graph_item_t *items, gsize count) {
+reset_io_graph_items(io_graph_item_t *items, size_t count, int hf_index _U_) {
io_graph_item_t *item;
- gsize i;
+ size_t i;
for (i = 0; i < count; i++) {
item = &items[i];
@@ -77,21 +88,70 @@ reset_io_graph_items(io_graph_item_t *items, gsize count) {
item->frames = 0;
item->bytes = 0;
item->fields = 0;
- item->int_max = 0;
- item->int_min = 0;
- item->int_tot = 0;
- item->float_max = 0;
- item->float_min = 0;
- item->float_tot = 0;
- item->double_max = 0;
- item->double_min = 0;
- item->double_tot = 0;
+ item->first_frame_in_invl = 0;
+ item->min_frame_in_invl = 0;
+ item->max_frame_in_invl = 0;
+ item->last_frame_in_invl = 0;
+
nstime_set_zero(&item->time_max);
nstime_set_zero(&item->time_min);
nstime_set_zero(&item->time_tot);
- item->first_frame_in_invl = 0;
- item->extreme_frame_in_invl = 0;
- item->last_frame_in_invl = 0;
+
+#if 0
+ /* XXX - On C, type punning is explicitly allowed since C99 so
+ * setting the nstime_t values to 0 is always sufficient.
+ * On C++ that appears technically to be undefined behavior (though
+ * I don't know of any compilers for which it doesn't work and I
+ * can't get UBSAN to complain about it) and this would be safer.
+ */
+ if (hf_index > 0) {
+
+ switch (proto_registrar_get_ftype(hf_index)) {
+
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ case FT_INT40:
+ case FT_INT48:
+ case FT_INT56:
+ case FT_INT64:
+ item->int_max = 0;
+ item->int_min = 0;
+ item->double_tot = 0;
+ break;
+
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_UINT40:
+ case FT_UINT48:
+ case FT_UINT56:
+ case FT_UINT64:
+ item->uint_max = 0;
+ item->uint_min = 0;
+ item->double_tot = 0;
+ break;
+
+ case FT_DOUBLE:
+ case FT_FLOAT:
+ item->double_max = 0;
+ item->double_min = 0;
+ item->double_tot = 0;
+ break;
+
+ case FT_RELATIVE_TIME:
+ nstime_set_zero(&item->time_max);
+ nstime_set_zero(&item->time_min);
+ nstime_set_zero(&item->time_tot);
+ break;
+
+ default:
+ break;
+ }
+ }
+#endif
}
}
@@ -100,10 +160,14 @@ reset_io_graph_items(io_graph_item_t *items, gsize count) {
* It is up to the caller to determine if the return value is valid.
*
* @param [in] pinfo Packet of interest.
- * @param [in] interval Time interval in milliseconds.
+ * @param [in] interval Time interval in microseconds
* @return Array index on success, -1 on failure.
+ *
+ * @note pinfo->rel_ts, and hence the index, is not affected by ignoring
+ * frames, but is affected by time references. (Ignoring frames before
+ * a time reference can be useful, though.)
*/
-int get_io_graph_index(packet_info *pinfo, int interval);
+int64_t get_io_graph_index(packet_info *pinfo, int interval);
/** Check field and item unit compatibility
*
@@ -139,11 +203,11 @@ double get_io_graph_item(const io_graph_item_t *items, io_graph_item_unit_t val_
* @param edt [in] Dissection information for advanced statistics. May be NULL.
* @param hf_index [in] Header field index for advanced statistics.
* @param item_unit [in] The type of unit to calculate. From IOG_ITEM_UNITS.
- * @param interval [in] Timing interval in ms.
- * @return TRUE if the update was successful, otherwise FALSE.
+ * @param interval [in] Timing interval in μs.
+ * @return true if the update was successful, otherwise false.
*/
-static inline gboolean
-update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, guint32 interval) {
+static inline bool
+update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_dissect_t *edt, int hf_index, int item_unit, uint32_t interval) {
io_graph_item_t *item = &items[idx];
/* Set the first and last frame num in current interval matching the target field+filter */
@@ -154,18 +218,18 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
if (edt && hf_index >= 0) {
GPtrArray *gp;
- guint i;
+ unsigned i;
gp = proto_get_finfo_ptr_array(edt->tree, hf_index);
if (!gp) {
- return FALSE;
+ return false;
}
/* Update the appropriate counters. If fields == 0, this is the first seen
* value so set any min/max values accordingly. */
for (i=0; i < gp->len; i++) {
- gint64 new_int64;
- guint64 new_uint64;
+ int64_t new_int64;
+ uint64_t new_uint64;
float new_float;
double new_double;
const nstime_t *new_time;
@@ -177,22 +241,15 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
case FT_UINT32:
new_uint64 = fvalue_get_uinteger(((field_info *)gp->pdata[i])->value);
- if ((new_uint64 > (guint64)item->int_max) || (item->fields == 0)) {
- item->int_max = new_uint64;
- item->double_max = (gdouble)new_uint64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
+ item->uint_max = new_uint64;
+ item->max_frame_in_invl = pinfo->num;
}
- if ((new_uint64 < (guint64)item->int_min) || (item->fields == 0)) {
- item->int_min = new_uint64;
- item->double_min = (gdouble)new_uint64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
+ item->uint_min = new_uint64;
+ item->min_frame_in_invl = pinfo->num;
}
- item->int_tot += new_uint64;
- item->double_tot += (gdouble)new_uint64;
+ item->double_tot += (double)new_uint64;
item->fields++;
break;
case FT_INT8:
@@ -202,20 +259,13 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
new_int64 = fvalue_get_sinteger(((field_info *)gp->pdata[i])->value);
if ((new_int64 > item->int_max) || (item->fields == 0)) {
item->int_max = new_int64;
- item->double_max = (gdouble)new_int64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->max_frame_in_invl = pinfo->num;
}
if ((new_int64 < item->int_min) || (item->fields == 0)) {
item->int_min = new_int64;
- item->double_min = (gdouble)new_int64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->min_frame_in_invl = pinfo->num;
}
- item->int_tot += new_int64;
- item->double_tot += (gdouble)new_int64;
+ item->double_tot += (double)new_int64;
item->fields++;
break;
case FT_UINT40:
@@ -223,22 +273,15 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
case FT_UINT56:
case FT_UINT64:
new_uint64 = fvalue_get_uinteger64(((field_info *)gp->pdata[i])->value);
- if ((new_uint64 > (guint64)item->int_max) || (item->fields == 0)) {
- item->int_max = new_uint64;
- item->double_max = (gdouble)new_uint64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ if ((new_uint64 > item->uint_max) || (item->fields == 0)) {
+ item->uint_max = new_uint64;
+ item->max_frame_in_invl = pinfo->num;
}
- if ((new_uint64 < (guint64)item->int_min) || (item->fields == 0)) {
- item->int_min = new_uint64;
- item->double_min = (gdouble)new_uint64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ if ((new_uint64 < item->uint_min) || (item->fields == 0)) {
+ item->uint_min = new_uint64;
+ item->min_frame_in_invl = pinfo->num;
}
- item->int_tot += new_uint64;
- item->double_tot += (gdouble)new_uint64;
+ item->double_tot += (double)new_uint64;
item->fields++;
break;
case FT_INT40:
@@ -248,52 +291,37 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
new_int64 = fvalue_get_sinteger64(((field_info *)gp->pdata[i])->value);
if ((new_int64 > item->int_max) || (item->fields == 0)) {
item->int_max = new_int64;
- item->double_max = (gdouble)new_int64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->max_frame_in_invl = pinfo->num;
}
if ((new_int64 < item->int_min) || (item->fields == 0)) {
item->int_min = new_int64;
- item->double_min = (gdouble)new_int64;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->min_frame_in_invl = pinfo->num;
}
- item->int_tot += new_int64;
- item->double_tot += (gdouble)new_int64;
+ item->double_tot += (double)new_int64;
item->fields++;
break;
case FT_FLOAT:
- new_float = (gfloat)fvalue_get_floating(((field_info *)gp->pdata[i])->value);
- if ((new_float > item->float_max) || (item->fields == 0)) {
- item->float_max = new_float;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ new_float = (float)fvalue_get_floating(((field_info *)gp->pdata[i])->value);
+ if ((new_float > item->double_max) || (item->fields == 0)) {
+ item->double_max = new_float;
+ item->max_frame_in_invl = pinfo->num;
}
- if ((new_float < item->float_min) || (item->fields == 0)) {
- item->float_min = new_float;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ if ((new_float < item->double_min) || (item->fields == 0)) {
+ item->double_min = new_float;
+ item->min_frame_in_invl = pinfo->num;
}
- item->float_tot += new_float;
+ item->double_tot += new_float;
item->fields++;
break;
case FT_DOUBLE:
new_double = fvalue_get_floating(((field_info *)gp->pdata[i])->value);
if ((new_double > item->double_max) || (item->fields == 0)) {
item->double_max = new_double;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->max_frame_in_invl = pinfo->num;
}
if ((new_double < item->double_min) || (item->fields == 0)) {
item->double_min = new_double;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->min_frame_in_invl = pinfo->num;
}
item->double_tot += new_double;
item->fields++;
@@ -304,20 +332,28 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
switch (item_unit) {
case IOG_ITEM_UNIT_CALC_LOAD:
{
- guint64 t, pt; /* time in us */
+ uint64_t t, pt; /* time in us */
int j;
/*
- * Add the time this call spanned each interval according to its contribution
- * to that interval.
+ * Add the time this call spanned each interval according to
+ * its contribution to that interval.
+ * If the call time is negative (unlikely, requires both an
+ * out of order capture file plus retransmission), ignore.
*/
+ const nstime_t time_zero = NSTIME_INIT_ZERO;
+ if (nstime_cmp(new_time, &time_zero) < 0) {
+ break;
+ }
t = new_time->secs;
t = t * 1000000 + new_time->nsecs / 1000;
j = idx;
/*
* Handle current interval
+ * This cannot be negative, because get_io_graph_index
+ * returns an invalid interval if so.
*/
pt = pinfo->rel_ts.secs * 1000000 + pinfo->rel_ts.nsecs / 1000;
- pt = pt % (interval * 1000);
+ pt = pt % interval;
if (pt > t) {
pt = t;
}
@@ -330,14 +366,15 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
load_item->time_tot.secs++;
load_item->time_tot.nsecs -= 1000000000;
}
+ load_item->fields++;
if (j == 0) {
break;
}
j--;
t -= pt;
- if (t > (guint64) interval * 1000) {
- pt = (guint64) interval * 1000;
+ if (t > (uint64_t) interval) {
+ pt = (uint64_t) interval;
} else {
pt = t;
}
@@ -345,23 +382,15 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
break;
}
default:
- if ( (new_time->secs > item->time_max.secs)
- || ( (new_time->secs == item->time_max.secs)
- && (new_time->nsecs > item->time_max.nsecs))
+ if ( (nstime_cmp(new_time, &item->time_max) > 0)
|| (item->fields == 0)) {
item->time_max = *new_time;
- if (item_unit == IOG_ITEM_UNIT_CALC_MAX) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->max_frame_in_invl = pinfo->num;
}
- if ( (new_time->secs<item->time_min.secs)
- || ( (new_time->secs == item->time_min.secs)
- && (new_time->nsecs < item->time_min.nsecs))
+ if ( (nstime_cmp(new_time, &item->time_min) < 0)
|| (item->fields == 0)) {
item->time_min = *new_time;
- if (item_unit == IOG_ITEM_UNIT_CALC_MIN) {
- item->extreme_frame_in_invl = pinfo->num;
- }
+ item->min_frame_in_invl = pinfo->num;
}
nstime_add(&item->time_tot, new_time);
item->fields++;
@@ -393,7 +422,7 @@ update_io_graph_item(io_graph_item_t *items, int idx, packet_info *pinfo, epan_d
item->frames++;
item->bytes += pinfo->fd->pkt_len;
- return TRUE;
+ return true;
}