diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:26 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-09-19 04:14:26 +0000 |
commit | c4e8a3222648fcf22ca207f1815ebbf7cd144eeb (patch) | |
tree | 93d5c6aa93d9987680dd1adad5685e2ad698f223 /ui/io_graph_item.h | |
parent | Adding upstream version 4.2.6. (diff) | |
download | wireshark-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.h | 287 |
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; } |