diff options
author | Frediano Ziglio <fziglio@redhat.com> | 2016-02-25 09:09:27 +0000 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2023-11-22 07:39:16 +0000 |
commit | 4683eaf98096a220e89e1154ddc153bce94293a7 (patch) | |
tree | 059f5baaf513e5b51deeef6b7ff0139074dc46d4 | |
parent | dbfebc419780f43e00a18f82cde6359abccb35f8 (diff) |
try do detect bandwidthstream_bug_francois
-rw-r--r-- | server/Makefile.am | 2 | ||||
-rw-r--r-- | server/bw-stats.c | 82 | ||||
-rw-r--r-- | server/bw-stats.h | 38 | ||||
-rw-r--r-- | server/meson.build | 2 | ||||
-rw-r--r-- | server/red-stream.cpp | 16 |
5 files changed, 139 insertions, 1 deletions
diff --git a/server/Makefile.am b/server/Makefile.am index 5260051b..57c30f4d 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -88,6 +88,8 @@ libserver_la_SOURCES = \ $(spice_built_sources) \ agent-msg-filter.c \ agent-msg-filter.h \ + bw-stats.c \ + bw-stats.h \ cache-item.h \ char-device.cpp \ char-device.h \ diff --git a/server/bw-stats.c b/server/bw-stats.c new file mode 100644 index 00000000..f72a3287 --- /dev/null +++ b/server/bw-stats.c @@ -0,0 +1,82 @@ +/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ +/* + Copyright (C) 2016 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <inttypes.h> +#include <sys/ioctl.h> +#ifdef HAVE_LINUX_SOCKIOS_H +#include <linux/sockios.h> /* SIOCOUTQ */ +#endif + +#include "bw-stats.h" + +void bandwidth_stats_init(BandwidthStatistics *stat) +{ + stat->first_time_valid = stat->last_time_valid = 0; +} + +void bandwidth_stats_destroy(BandwidthStatistics *stat) +{ +} + +void bandwidth_stats_update(BandwidthStatistics *stat, int socket, size_t size) +{ + /* try to understand if we buffer was full */ +#ifdef HAVE_LINUX_SOCKIOS_H /* SIOCOUTQ is a Linux only ioctl on sockets. */ + int so_unsent_size = 0; + +/* +sent queued unsent total sent +0 0 0 0 +100 100 0 0 +100 200 100 0 +-100 300 200 0 +100 150 50 150 = prev total + prev queued + bytes - queued +100 150 50 = 150 + 150 + 100 - 150 +*/ + + /* retrieving the occupied size of the socket's tcp snd buffer (unacked + unsent) */ + if (ioctl(socket, SIOCOUTQ, &so_unsent_size) == -1 || so_unsent_size <= size) { + /* TODO see if data was enough */ + stat->first_time_valid = stat->last_time_valid = 0; + return; + } + + red_time_t curr_time = spice_get_monotonic_time_ns(); + + /* if this the first valid data ? */ + if (!stat->first_time_valid) { + stat->first_time_valid = stat->last_time_valid = curr_time; + stat->total_bytes = 0; + stat->prev_unsent = so_unsent_size; + return; + } + + /* add this reading */ + stat->last_time_valid = curr_time; + stat->total_bytes += stat->prev_unsent + size - so_unsent_size; + stat->prev_unsent = so_unsent_size; +return; + printf("%zu / %" PRIu64 " %g\n", + stat->total_bytes, stat->last_time_valid - stat->first_time_valid, + stat->total_bytes * 1000000000.0 / (stat->last_time_valid - stat->first_time_valid)); +#endif +} diff --git a/server/bw-stats.h b/server/bw-stats.h new file mode 100644 index 00000000..8be690fc --- /dev/null +++ b/server/bw-stats.h @@ -0,0 +1,38 @@ +/* + Copyright (C) 2016 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef BW_STATS_H_ +#define BW_STATS_H_ + +#include "utils.h" + +SPICE_BEGIN_DECLS + +typedef struct BandwidthStatistics { + red_time_t first_time_valid, last_time_valid; + size_t prev_unsent, total_bytes; +} BandwidthStatistics; + +/* initialize structure to hold bandwidth computation */ +void bandwidth_stats_init(BandwidthStatistics *stat); +void bandwidth_stats_destroy(BandwidthStatistics *stat); +/* update bandwidth statistics */ +void bandwidth_stats_update(BandwidthStatistics *stat, int socket, size_t size); + +SPICE_END_DECLS + +#endif /* BW_STATS_H_ */ diff --git a/server/meson.build b/server/meson.build index a8da777f..3f1c67f7 100644 --- a/server/meson.build +++ b/server/meson.build @@ -69,6 +69,8 @@ spice_server_sources = [ spice_server_enums, 'agent-msg-filter.c', 'agent-msg-filter.h', + 'bw-stats.c', + 'bw-stats.h', 'cache-item.h', 'char-device.cpp', 'char-device.h', diff --git a/server/red-stream.cpp b/server/red-stream.cpp index 89222702..ede3dd48 100644 --- a/server/red-stream.cpp +++ b/server/red-stream.cpp @@ -42,6 +42,7 @@ #include "red-stream.h" #include "reds.h" #include "websocket.h" +#include "bw-stats.h" // compatibility for *BSD systems #if !defined(TCP_CORK) && !defined(_WIN32) @@ -102,6 +103,8 @@ struct RedStreamPrivate { ssize_t (*write)(RedStream *s, const void *buf, size_t nbyte); ssize_t (*writev)(RedStream *s, const struct iovec *iov, int iovcnt); + BandwidthStatistics bw_stat; + RedsState *reds; SpiceCoreInterfaceInternal *core; }; @@ -123,9 +126,19 @@ static inline int socket_set_cork(int socket, int enabled) } #endif +/* update bandwidth statistics + */ +static void stream_bandwidth_compute_update(RedStream *s, ssize_t size) +{ + if (size > 0) + bandwidth_stats_update(&s->priv->bw_stat, s->socket, size); +} + static ssize_t stream_write_cb(RedStream *s, const void *buf, size_t size) { - return socket_write(s->socket, buf, size); + ssize_t ret = socket_write(s->socket, buf, size); + stream_bandwidth_compute_update(s, ret); + return ret; } static ssize_t stream_writev_cb(RedStream *s, const struct iovec *iov, int iovcnt) @@ -144,6 +157,7 @@ static ssize_t stream_writev_cb(RedStream *s, const struct iovec *iov, int iovcn expected += iov[i].iov_len; } n = socket_writev(s->socket, iov, tosend); + stream_bandwidth_compute_update(s, n); if (n <= expected) { if (n > 0) ret += n; |