mirror of
https://github.com/weechat/weechat.git
synced 2026-06-25 04:16:38 +02:00
xfer: compute speed and ETA with microsecond precision
This commit is contained in:
committed by
Sébastien Helleu
parent
ca22e49041
commit
15e2da3aac
@@ -23,6 +23,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
@@ -217,12 +218,22 @@ xfer_buffer_refresh (const char *hotlist)
|
||||
eta[0] = '\0';
|
||||
if (ptr_xfer->status == XFER_STATUS_ACTIVE)
|
||||
{
|
||||
snprintf (eta, sizeof (eta),
|
||||
"%s: %.2llu:%.2llu:%.2llu - ",
|
||||
_("ETA"),
|
||||
ptr_xfer->eta / 3600,
|
||||
(ptr_xfer->eta / 60) % 60,
|
||||
ptr_xfer->eta % 60);
|
||||
if (ptr_xfer->eta != ULLONG_MAX)
|
||||
{
|
||||
snprintf (eta, sizeof (eta),
|
||||
"%s: %.2llu:%.2llu:%.2llu - ",
|
||||
_("ETA"),
|
||||
ptr_xfer->eta / 3600,
|
||||
(ptr_xfer->eta / 60) % 60,
|
||||
ptr_xfer->eta % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (eta, sizeof (eta),
|
||||
"%s: %s - ",
|
||||
_("ETA"),
|
||||
_("unknown"));
|
||||
}
|
||||
}
|
||||
|
||||
/* display second line for file with status, progress bar and estimated time */
|
||||
|
||||
@@ -170,7 +170,7 @@ xfer_command_xfer_list (int full)
|
||||
ptr_xfer->remote_address_str,
|
||||
ptr_xfer->port);
|
||||
date[0] = '\0';
|
||||
date_tmp = localtime (&(ptr_xfer->start_transfer));
|
||||
date_tmp = localtime (&(ptr_xfer->start_transfer.tv_sec));
|
||||
if (date_tmp)
|
||||
{
|
||||
if (strftime (date, sizeof (date),
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../weechat-plugin.h"
|
||||
#include "xfer.h"
|
||||
@@ -304,37 +305,44 @@ xfer_file_find_filename (struct t_xfer *xfer)
|
||||
void
|
||||
xfer_file_calculate_speed (struct t_xfer *xfer, int ended)
|
||||
{
|
||||
time_t local_time, elapsed;
|
||||
unsigned long long bytes_per_sec_total;
|
||||
struct timeval local_time;
|
||||
long long elapsed_usec;
|
||||
double bytes_per_usec_total;
|
||||
|
||||
local_time = time (NULL);
|
||||
if (ended || local_time > xfer->last_check_time)
|
||||
gettimeofday (&local_time, NULL);
|
||||
if (ended || (weechat_util_timeval_cmp (&local_time, &xfer->last_check_time) > 0))
|
||||
{
|
||||
if (ended)
|
||||
{
|
||||
/* calculate bytes per second (global) */
|
||||
elapsed = local_time - xfer->start_transfer;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
xfer->bytes_per_sec = (xfer->pos - xfer->start_resume) / elapsed;
|
||||
elapsed_usec = weechat_util_timeval_diff (&xfer->start_transfer, &local_time);
|
||||
if (elapsed_usec == 0)
|
||||
elapsed_usec = 1;
|
||||
xfer->bytes_per_sec = ((xfer->pos - xfer->start_resume) * 1000000.0) / elapsed_usec;
|
||||
xfer->eta = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* calculate ETA */
|
||||
elapsed = local_time - xfer->start_transfer;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
bytes_per_sec_total = (xfer->pos - xfer->start_resume) / elapsed;
|
||||
if (bytes_per_sec_total == 0)
|
||||
bytes_per_sec_total = 1;
|
||||
xfer->eta = (xfer->size - xfer->pos) / bytes_per_sec_total;
|
||||
elapsed_usec = weechat_util_timeval_diff (&xfer->start_transfer, &local_time);
|
||||
if (elapsed_usec == 0)
|
||||
{
|
||||
xfer->eta = ULLONG_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_per_usec_total = (double)(xfer->pos - xfer->start_resume) / (double)elapsed_usec;
|
||||
if (bytes_per_usec_total == 0)
|
||||
xfer->eta = ULLONG_MAX;
|
||||
else
|
||||
xfer->eta = (xfer->size - xfer->pos) / bytes_per_usec_total / 1000000.0;
|
||||
}
|
||||
|
||||
/* calculate bytes per second (since last check time) */
|
||||
elapsed = local_time - xfer->last_check_time;
|
||||
if (elapsed == 0)
|
||||
elapsed = 1;
|
||||
xfer->bytes_per_sec = (xfer->pos - xfer->last_check_pos) / elapsed;
|
||||
elapsed_usec = weechat_util_timeval_diff (&xfer->last_check_time, &local_time);
|
||||
if (elapsed_usec == 0)
|
||||
elapsed_usec = 1;
|
||||
xfer->bytes_per_sec = ((xfer->pos - xfer->last_check_pos) * 1000000.0) / elapsed_usec;
|
||||
}
|
||||
xfer->last_check_time = local_time;
|
||||
xfer->last_check_pos = xfer->pos;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -287,8 +288,8 @@ xfer_network_child_read_cb (const void *pointer, void *data, int fd)
|
||||
{
|
||||
/* connection was successful by child, init transfer times */
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer->start_transfer = time (NULL);
|
||||
xfer->last_check_time = time (NULL);
|
||||
gettimeofday (&xfer->start_transfer, NULL);
|
||||
xfer->last_check_time = xfer->start_transfer;
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
}
|
||||
else
|
||||
@@ -571,7 +572,7 @@ xfer_network_fd_cb (const void *pointer, void *data, int fd)
|
||||
xfer_set_remote_address (xfer, (struct sockaddr *)&addr, length,
|
||||
str_address);
|
||||
xfer->status = XFER_STATUS_ACTIVE;
|
||||
xfer->start_transfer = time (NULL);
|
||||
gettimeofday (&xfer->start_transfer, NULL);
|
||||
xfer_buffer_refresh (WEECHAT_HOTLIST_MESSAGE);
|
||||
switch (xfer->type)
|
||||
{
|
||||
|
||||
+15
-6
@@ -24,6 +24,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
@@ -544,7 +545,7 @@ xfer_alloc (void)
|
||||
new_xfer->send_ack = weechat_config_boolean (xfer_config_network_send_ack);
|
||||
new_xfer->blocksize = weechat_config_integer (xfer_config_network_blocksize);
|
||||
new_xfer->start_time = time_now;
|
||||
new_xfer->start_transfer = time_now;
|
||||
gettimeofday (&new_xfer->start_transfer, NULL);
|
||||
new_xfer->sock = -1;
|
||||
new_xfer->child_pid = 0;
|
||||
new_xfer->child_read = -1;
|
||||
@@ -560,7 +561,7 @@ xfer_alloc (void)
|
||||
new_xfer->pos = 0;
|
||||
new_xfer->ack = 0;
|
||||
new_xfer->start_resume = 0;
|
||||
new_xfer->last_check_time = time_now;
|
||||
new_xfer->last_check_time = new_xfer->start_transfer;
|
||||
new_xfer->last_check_pos = time_now;
|
||||
new_xfer->last_activity = 0;
|
||||
new_xfer->bytes_per_sec = 0;
|
||||
@@ -1644,7 +1645,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_time (ptr_item, "start_time", xfer->start_time))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_time (ptr_item, "start_transfer", xfer->start_transfer))
|
||||
if (!weechat_infolist_new_var_time (ptr_item, "start_transfer", xfer->start_transfer.tv_sec))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "start_transfer_usec", xfer->start_transfer.tv_usec))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "sock", xfer->sock))
|
||||
return 0;
|
||||
@@ -1679,7 +1682,9 @@ xfer_add_to_infolist (struct t_infolist *infolist, struct t_xfer *xfer)
|
||||
snprintf (value, sizeof (value), "%llu", xfer->start_resume);
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "start_resume", value))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_time (ptr_item, "last_check_time", xfer->last_check_time))
|
||||
if (!weechat_infolist_new_var_time (ptr_item, "last_check_time", xfer->last_check_time.tv_sec))
|
||||
return 0;
|
||||
if (!weechat_infolist_new_var_integer (ptr_item, "last_check_time_usec", xfer->last_check_time.tv_usec))
|
||||
return 0;
|
||||
snprintf (value, sizeof (value), "%llu", xfer->last_check_pos);
|
||||
if (!weechat_infolist_new_var_string (ptr_item, "last_check_pos", value))
|
||||
@@ -1746,7 +1751,9 @@ xfer_print_log (void)
|
||||
weechat_log_printf (" fast_send . . . . . . . : %d", ptr_xfer->fast_send);
|
||||
weechat_log_printf (" blocksize . . . . . . . : %d", ptr_xfer->blocksize);
|
||||
weechat_log_printf (" start_time. . . . . . . : %lld", (long long)ptr_xfer->start_time);
|
||||
weechat_log_printf (" start_transfer. . . . . : %lld", (long long)ptr_xfer->start_transfer);
|
||||
weechat_log_printf (" start_transfer. . . . . : tv_sec:%lld, tv_usec:%ld",
|
||||
(long long)(ptr_xfer->start_transfer.tv_sec),
|
||||
(long)(ptr_xfer->start_transfer.tv_usec));
|
||||
weechat_log_printf (" sock. . . . . . . . . . : %d", ptr_xfer->sock);
|
||||
weechat_log_printf (" child_pid . . . . . . . : %d", ptr_xfer->child_pid);
|
||||
weechat_log_printf (" child_read. . . . . . . : %d", ptr_xfer->child_read);
|
||||
@@ -1762,7 +1769,9 @@ xfer_print_log (void)
|
||||
weechat_log_printf (" pos . . . . . . . . . . : %llu", ptr_xfer->pos);
|
||||
weechat_log_printf (" ack . . . . . . . . . . : %llu", ptr_xfer->ack);
|
||||
weechat_log_printf (" start_resume. . . . . . : %llu", ptr_xfer->start_resume);
|
||||
weechat_log_printf (" last_check_time . . . . : %lld", (long long)ptr_xfer->last_check_time);
|
||||
weechat_log_printf (" last_check_time . . . . : tv_sec:%lld, tv_usec:%ld",
|
||||
(long long)(ptr_xfer->last_check_time.tv_sec),
|
||||
(long)(ptr_xfer->last_check_time.tv_usec));
|
||||
weechat_log_printf (" last_check_pos. . . . . : %llu", ptr_xfer->last_check_pos);
|
||||
weechat_log_printf (" last_activity . . . . . : %lld", (long long)ptr_xfer->last_activity);
|
||||
weechat_log_printf (" bytes_per_sec . . . . . : %llu", ptr_xfer->bytes_per_sec);
|
||||
|
||||
@@ -171,7 +171,7 @@ struct t_xfer
|
||||
int send_ack; /* send acks on file receive */
|
||||
int blocksize; /* block size for sending file */
|
||||
time_t start_time; /* time when xfer started */
|
||||
time_t start_transfer; /* time when xfer transfer started */
|
||||
struct timeval start_transfer; /* time when xfer transfer started */
|
||||
int sock; /* socket for connection */
|
||||
pid_t child_pid; /* pid of child process (send/recv) */
|
||||
int child_read; /* to read into child pipe */
|
||||
@@ -189,7 +189,7 @@ struct t_xfer
|
||||
unsigned long long pos; /* number of bytes received/sent */
|
||||
unsigned long long ack; /* number of bytes received OK */
|
||||
unsigned long long start_resume; /* start of resume (in bytes) */
|
||||
time_t last_check_time; /* last time we checked bytes snt/rcv*/
|
||||
struct timeval last_check_time; /* last time we checked bytes snt/rcv*/
|
||||
unsigned long long last_check_pos; /* bytes sent/recv at last check */
|
||||
time_t last_activity; /* time of last byte received/sent */
|
||||
unsigned long long bytes_per_sec; /* bytes per second */
|
||||
|
||||
Reference in New Issue
Block a user