Move responsibility for recording read/written bytes

Previously this was done as part of the refill callback, but there's
no real reason to do it like that.  Since we're trying to remove the
refill callback completely, we can do this work as part of
record_num_bytes_transferred_impl(), which already does quite a lot
of this.
This commit is contained in:
Nick Mathewson 2018-04-17 16:19:45 -04:00
parent a2acb9b9e9
commit 780d1b44cf
4 changed files with 41 additions and 34 deletions

View File

@ -85,6 +85,7 @@
#include "ext_orport.h" #include "ext_orport.h"
#include "geoip.h" #include "geoip.h"
#include "main.h" #include "main.h"
#include "hibernate.h"
#include "hs_common.h" #include "hs_common.h"
#include "hs_ident.h" #include "hs_ident.h"
#include "nodelist.h" #include "nodelist.h"
@ -2989,6 +2990,10 @@ global_write_bucket_low(connection_t *conn, size_t attempt, int priority)
return 0; return 0;
} }
/** When did we last tell the accounting subsystem about transmitted
* bandwidth? */
static time_t last_recorded_accounting_at = 0;
/** Helper: adjusts our bandwidth history and informs the controller as /** Helper: adjusts our bandwidth history and informs the controller as
* appropriate, given that we have just read <b>num_read</b> bytes and written * appropriate, given that we have just read <b>num_read</b> bytes and written
* <b>num_written</b> bytes on <b>conn</b>. */ * <b>num_written</b> bytes on <b>conn</b>. */
@ -3019,6 +3024,20 @@ record_num_bytes_transferred_impl(connection_t *conn,
} }
if (conn->type == CONN_TYPE_EXIT) if (conn->type == CONN_TYPE_EXIT)
rep_hist_note_exit_bytes(conn->port, num_written, num_read); rep_hist_note_exit_bytes(conn->port, num_written, num_read);
/* Remember these bytes towards statistics. */
stats_increment_bytes_read_and_written(num_read, num_written);
/* Remember these bytes towards accounting. */
if (accounting_is_enabled(get_options())) {
if (now > last_recorded_accounting_at && last_recorded_accounting_at) {
accounting_add_bytes(num_read, num_written,
now - last_recorded_accounting_at);
} else {
accounting_add_bytes(num_read, num_written, 0);
}
last_recorded_accounting_at = now;
}
} }
/** We just read <b>num_read</b> and wrote <b>num_written</b> bytes /** We just read <b>num_read</b> and wrote <b>num_written</b> bytes
@ -5196,6 +5215,7 @@ connection_free_all(void)
tor_free(last_interface_ipv4); tor_free(last_interface_ipv4);
tor_free(last_interface_ipv6); tor_free(last_interface_ipv6);
last_recorded_accounting_at = 0;
} }
/** Log a warning, and possibly emit a control event, that <b>received</b> came /** Log a warning, and possibly emit a control event, that <b>received</b> came

View File

@ -297,7 +297,7 @@ accounting_get_end_time,(void))
return interval_end_time; return interval_end_time;
} }
/** Called from main.c to tell us that <b>seconds</b> seconds have /** Called from connection.c to tell us that <b>seconds</b> seconds have
* passed, <b>n_read</b> bytes have been read, and <b>n_written</b> * passed, <b>n_read</b> bytes have been read, and <b>n_written</b>
* bytes have been written. */ * bytes have been written. */
void void

View File

@ -159,13 +159,6 @@ token_bucket_rw_t global_bucket;
/* Token bucket for relayed traffic. */ /* Token bucket for relayed traffic. */
token_bucket_rw_t global_relayed_bucket; token_bucket_rw_t global_relayed_bucket;
/** What was the read/write bucket before the last second_elapsed_callback()
* call? (used to determine how many bytes we've read). */
static size_t stats_prev_global_read_bucket;
/** What was the write bucket before the last second_elapsed_callback() call?
* (used to determine how many bytes we've written). */
static size_t stats_prev_global_write_bucket;
/* DOCDOC stats_prev_n_read */ /* DOCDOC stats_prev_n_read */
static uint64_t stats_prev_n_read = 0; static uint64_t stats_prev_n_read = 0;
/* DOCDOC stats_prev_n_written */ /* DOCDOC stats_prev_n_written */
@ -479,21 +472,37 @@ get_connection_array, (void))
return connection_array; return connection_array;
} }
/** Provides the traffic read and written over the life of the process. */ /**
* Return the amount of network traffic read, in bytes, over the life of this
* process.
*/
MOCK_IMPL(uint64_t, MOCK_IMPL(uint64_t,
get_bytes_read,(void)) get_bytes_read,(void))
{ {
return stats_n_bytes_read; return stats_n_bytes_read;
} }
/* DOCDOC get_bytes_written */ /**
* Return the amount of network traffic read, in bytes, over the life of this
* process.
*/
MOCK_IMPL(uint64_t, MOCK_IMPL(uint64_t,
get_bytes_written,(void)) get_bytes_written,(void))
{ {
return stats_n_bytes_written; return stats_n_bytes_written;
} }
/**
* Increment the amount of network traffic read and written, over the life of
* this process.
*/
void
stats_increment_bytes_read_and_written(uint64_t r, uint64_t w)
{
stats_n_bytes_read += r;
stats_n_bytes_written += w;
}
/** Set the event mask on <b>conn</b> to <b>events</b>. (The event /** Set the event mask on <b>conn</b> to <b>events</b>. (The event
* mask is a bitmask whose bits are READ_EVENT and WRITE_EVENT) * mask is a bitmask whose bits are READ_EVENT and WRITE_EVENT)
*/ */
@ -2374,12 +2383,7 @@ refill_callback(periodic_timer_t *timer, void *arg)
{ {
struct timeval now; struct timeval now;
size_t bytes_written;
size_t bytes_read;
int milliseconds_elapsed = 0; int milliseconds_elapsed = 0;
int seconds_rolled_over = 0;
const or_options_t *options = get_options();
(void)timer; (void)timer;
(void)arg; (void)arg;
@ -2392,28 +2396,13 @@ refill_callback(periodic_timer_t *timer, void *arg)
if (mdiff > INT_MAX) if (mdiff > INT_MAX)
mdiff = INT_MAX; mdiff = INT_MAX;
milliseconds_elapsed = (int)mdiff; milliseconds_elapsed = (int)mdiff;
seconds_rolled_over = (int)(now.tv_sec -
refill_timer_current_millisecond.tv_sec);
} }
bytes_written = stats_prev_global_write_bucket -
token_bucket_rw_get_write(&global_bucket);
bytes_read = stats_prev_global_read_bucket -
token_bucket_rw_get_read(&global_bucket);
stats_n_bytes_read += bytes_read;
stats_n_bytes_written += bytes_written;
if (accounting_is_enabled(options) && milliseconds_elapsed >= 0)
accounting_add_bytes(bytes_read, bytes_written, seconds_rolled_over);
if (milliseconds_elapsed > 0) { if (milliseconds_elapsed > 0) {
connection_bucket_refill_all((time_t)now.tv_sec, connection_bucket_refill_all((time_t)now.tv_sec,
monotime_coarse_get_stamp()); monotime_coarse_get_stamp());
} }
stats_prev_global_read_bucket = token_bucket_rw_get_read(&global_bucket);
stats_prev_global_write_bucket = token_bucket_rw_get_write(&global_bucket);
/* remember what time it is, for next time */ /* remember what time it is, for next time */
refill_timer_current_millisecond = now; refill_timer_current_millisecond = now;
} }
@ -2621,8 +2610,6 @@ do_main_loop(void)
/* Set up our buckets */ /* Set up our buckets */
connection_bucket_init(); connection_bucket_init();
stats_prev_global_read_bucket = token_bucket_rw_get_read(&global_bucket);
stats_prev_global_write_bucket = token_bucket_rw_get_write(&global_bucket);
/* initialize the bootstrap status events to know we're starting up */ /* initialize the bootstrap status events to know we're starting up */
control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0); control_event_bootstrap(BOOTSTRAP_STATUS_STARTING, 0);
@ -3502,7 +3489,6 @@ tor_free_all(int postfork)
memset(&global_bucket, 0, sizeof(global_bucket)); memset(&global_bucket, 0, sizeof(global_bucket));
memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket)); memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket));
stats_prev_global_read_bucket = stats_prev_global_write_bucket = 0;
stats_prev_n_read = stats_prev_n_written = 0; stats_prev_n_read = stats_prev_n_written = 0;
stats_n_bytes_read = stats_n_bytes_written = 0; stats_n_bytes_read = stats_n_bytes_written = 0;
time_of_process_start = 0; time_of_process_start = 0;

View File

@ -28,6 +28,7 @@ int connection_is_on_closeable_list(connection_t *conn);
MOCK_DECL(smartlist_t *, get_connection_array, (void)); MOCK_DECL(smartlist_t *, get_connection_array, (void));
MOCK_DECL(uint64_t,get_bytes_read,(void)); MOCK_DECL(uint64_t,get_bytes_read,(void));
MOCK_DECL(uint64_t,get_bytes_written,(void)); MOCK_DECL(uint64_t,get_bytes_written,(void));
void stats_increment_bytes_read_and_written(uint64_t r, uint64_t w);
/** Bitmask for events that we can turn on and off with /** Bitmask for events that we can turn on and off with
* connection_watch_events. */ * connection_watch_events. */