From 14fe0d585916f4d8fdba64b419778c47ffd64b16 Mon Sep 17 00:00:00 2001 From: Andrea Shepard Date: Mon, 1 Oct 2012 01:51:31 -0700 Subject: Remove EWMA code from relay.{c,h}; it goes to a circuitmux policy now --- src/or/relay.c | 332 --------------------------------------------------------- src/or/relay.h | 3 - 2 files changed, 335 deletions(-) (limited to 'src') diff --git a/src/or/relay.c b/src/or/relay.c index e3b383ba7..d0341625f 100644 --- a/src/or/relay.c +++ b/src/or/relay.c @@ -10,7 +10,6 @@ * receiving from circuits, plus queuing on circuits. **/ -#include #define RELAY_PRIVATE #include "or.h" #include "buffers.h" @@ -1972,245 +1971,6 @@ cell_queue_pop(cell_queue_t *queue) return cell; } -#if 0 -/** Helper for sorting cell_ewma_t values in their priority queue. */ -static int -compare_cell_ewma_counts(const void *p1, const void *p2) -{ - const cell_ewma_t *e1=p1, *e2=p2; - if (e1->cell_count < e2->cell_count) - return -1; - else if (e1->cell_count > e2->cell_count) - return 1; - else - return 0; -} - -/** Given a cell_ewma_t, return a pointer to the circuit containing it. */ -static circuit_t * -cell_ewma_to_circuit(cell_ewma_t *ewma) -{ - if (ewma->is_for_p_chan) { - /* This is an or_circuit_t's p_cell_ewma. */ - or_circuit_t *orcirc = SUBTYPE_P(ewma, or_circuit_t, p_cell_ewma); - return TO_CIRCUIT(orcirc); - } else { - /* This is some circuit's n_cell_ewma. */ - return SUBTYPE_P(ewma, circuit_t, n_cell_ewma); - } -} - -/* ==== Functions for scaling cell_ewma_t ==== - - When choosing which cells to relay first, we favor circuits that have been - quiet recently. This gives better latency on connections that aren't - pushing lots of data, and makes the network feel more interactive. - - Conceptually, we take an exponentially weighted mean average of the number - of cells a circuit has sent, and allow active circuits (those with cells to - relay) to send cells in reverse order of their exponentially-weighted mean - average (EWMA) cell count. [That is, a cell sent N seconds ago 'counts' - F^N times as much as a cell sent now, for 0now, compute the cell_ewma tick in which it occurs - * and the fraction of the tick that has elapsed between the start of the tick - * and now. Return the former and store the latter in - * *remainder_out. - * - * These tick values are not meant to be shared between Tor instances, or used - * for other purposes. */ -static unsigned -cell_ewma_tick_from_timeval(const struct timeval *now, - double *remainder_out) -{ - unsigned res = (unsigned) (now->tv_sec / EWMA_TICK_LEN); - /* rem */ - double rem = (now->tv_sec % EWMA_TICK_LEN) + - ((double)(now->tv_usec)) / 1.0e6; - *remainder_out = rem / EWMA_TICK_LEN; - return res; -} - -/** Compute and return the current cell_ewma tick. */ -unsigned -cell_ewma_get_tick(void) -{ - return ((unsigned)approx_time() / EWMA_TICK_LEN); -} - -/** The per-tick scale factor to be used when computing cell-count EWMA - * values. (A cell sent N ticks before the start of the current tick - * has value ewma_scale_factor ** N.) - */ -static double ewma_scale_factor = 0.1; -/* DOCDOC ewma_enabled */ -static int ewma_enabled = 0; - -/*DOCDOC*/ -#define EPSILON 0.00001 -/*DOCDOC*/ -#define LOG_ONEHALF -0.69314718055994529 - -/** Adjust the global cell scale factor based on options */ -void -cell_ewma_set_scale_factor(const or_options_t *options, - const networkstatus_t *consensus) -{ - int32_t halflife_ms; - double halflife; - const char *source; - if (options && options->CircuitPriorityHalflife >= -EPSILON) { - halflife = options->CircuitPriorityHalflife; - source = "CircuitPriorityHalflife in configuration"; - } else if (consensus && (halflife_ms = networkstatus_get_param( - consensus, "CircuitPriorityHalflifeMsec", - -1, -1, INT32_MAX)) >= 0) { - halflife = ((double)halflife_ms)/1000.0; - source = "CircuitPriorityHalflifeMsec in consensus"; - } else { - halflife = EWMA_DEFAULT_HALFLIFE; - source = "Default value"; - } - - if (halflife <= EPSILON) { - /* The cell EWMA algorithm is disabled. */ - ewma_scale_factor = 0.1; - ewma_enabled = 0; - log_info(LD_OR, - "Disabled cell_ewma algorithm because of value in %s", - source); - } else { - /* convert halflife into halflife-per-tick. */ - halflife /= EWMA_TICK_LEN; - /* compute per-tick scale factor. */ - ewma_scale_factor = exp( LOG_ONEHALF / halflife ); - ewma_enabled = 1; - log_info(LD_OR, - "Enabled cell_ewma algorithm because of value in %s; " - "scale factor is %f per %d seconds", - source, ewma_scale_factor, EWMA_TICK_LEN); - } -} - -/** Return the multiplier necessary to convert the value of a cell sent in - * 'from_tick' to one sent in 'to_tick'. */ -static INLINE double -get_scale_factor(unsigned from_tick, unsigned to_tick) -{ - /* This math can wrap around, but that's okay: unsigned overflow is - well-defined */ - int diff = (int)(to_tick - from_tick); - return pow(ewma_scale_factor, diff); -} - -/** Adjust the cell count of ewma so that it is scaled with respect to - * cur_tick */ -static void -scale_single_cell_ewma(cell_ewma_t *ewma, unsigned cur_tick) -{ - double factor = get_scale_factor(ewma->last_adjusted_tick, cur_tick); - ewma->cell_count *= factor; - ewma->last_adjusted_tick = cur_tick; -} - -/** Adjust the cell count of every active circuit on chan so - * that they are scaled with respect to cur_tick */ -static void -scale_active_circuits(channel_t *chan, unsigned cur_tick) -{ - double factor; - - tor_assert(chan); - - factor = - get_scale_factor( - chan->active_circuit_pqueue_last_recalibrated, - cur_tick); - /** Ordinarily it isn't okay to change the value of an element in a heap, - * but it's okay here, since we are preserving the order. */ - SMARTLIST_FOREACH_BEGIN( - chan->active_circuit_pqueue, - cell_ewma_t *, e) { - tor_assert(e->last_adjusted_tick == - chan->active_circuit_pqueue_last_recalibrated); - e->cell_count *= factor; - e->last_adjusted_tick = cur_tick; - } SMARTLIST_FOREACH_END(e); - chan->active_circuit_pqueue_last_recalibrated = cur_tick; -} - -/** Rescale ewma to the same scale as chan, and add it to - * chan's priority queue of active circuits */ -static void -add_cell_ewma_to_chan(channel_t *chan, cell_ewma_t *ewma) -{ - tor_assert(chan); - tor_assert(ewma); - tor_assert(ewma->heap_index == -1); - - scale_single_cell_ewma( - ewma, - chan->active_circuit_pqueue_last_recalibrated); - - smartlist_pqueue_add(chan->active_circuit_pqueue, - compare_cell_ewma_counts, - STRUCT_OFFSET(cell_ewma_t, heap_index), - ewma); -} - -/** Remove ewma from chan's priority queue of active circuits */ -static void -remove_cell_ewma_from_chan(channel_t *chan, cell_ewma_t *ewma) -{ - tor_assert(chan); - tor_assert(ewma); - tor_assert(ewma->heap_index != -1); - - smartlist_pqueue_remove(chan->active_circuit_pqueue, - compare_cell_ewma_counts, - STRUCT_OFFSET(cell_ewma_t, heap_index), - ewma); -} - -/** Remove and return the first cell_ewma_t from chan's priority queue of - * active circuits. Requires that the priority queue is nonempty. */ -static cell_ewma_t * -pop_first_cell_ewma_from_chan(channel_t *chan) -{ - tor_assert(chan); - - return smartlist_pqueue_pop(chan->active_circuit_pqueue, - compare_cell_ewma_counts, - STRUCT_OFFSET(cell_ewma_t, heap_index)); -} -#endif - /** * Update the number of cells available on the circuit's n_chan or p_chan's * circuit mux. @@ -2335,15 +2095,6 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) int streams_blocked; packed_cell_t *cell; -#if 0 - /* The current (hi-res) time */ - struct timeval now_hires; - - /* The EWMA cell counter for the circuit we're flushing. */ - cell_ewma_t *cell_ewma = NULL; - double ewma_increment = -1; -#endif - /* Get the cmux */ tor_assert(chan); tor_assert(chan->cmux); @@ -2356,26 +2107,6 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) if (!circ) break; assert_cmux_ok_paranoid(chan); -#if 0 - /* This will go in circuitmux_get_first_active_circuit() */ - /* See if we're doing the ewma circuit selection algorithm. */ - if (ewma_enabled) { - unsigned tick; - double fractional_tick; - tor_gettimeofday_cached(&now_hires); - tick = cell_ewma_tick_from_timeval(&now_hires, &fractional_tick); - - if (tick != chan->active_circuit_pqueue_last_recalibrated) { - scale_active_circuits(chan, tick); - } - - ewma_increment = pow(ewma_scale_factor, -fractional_tick); - - cell_ewma = smartlist_get(chan->active_circuit_pqueue, 0); - circ = cell_ewma_to_circuit(cell_ewma); - } -#endif - if (circ->n_chan == chan) { queue = &circ->n_chan_cells; streams_blocked = circ->streams_blocked_on_n_chan; @@ -2460,28 +2191,6 @@ channel_flush_from_first_active_circuit(channel_t *chan, int max) if (streams_blocked && queue->n <= CELL_QUEUE_LOWWATER_SIZE) set_streams_blocked_on_circ(circ, chan, 0, 0); /* unblock streams */ -#if 0 - if (cell_ewma) { - cell_ewma_t *tmp; - cell_ewma->cell_count += ewma_increment; - /* We pop and re-add the cell_ewma_t here, not above, since we need to - * re-add it immediately to keep the priority queue consistent with - * the linked-list implementation */ - tmp = pop_first_cell_ewma_from_chan(chan); - tor_assert(tmp == cell_ewma); - add_cell_ewma_to_chan(chan, cell_ewma); - } - if (!ewma_enabled && circ != chan->active_circuits) { - /* If this happens, the current circuit just got made inactive by - * a call in connection_write_to_buf(). That's nothing to worry about: - * circuit_make_inactive_on_conn() already advanced chan->active_circuits - * for us. - */ - assert_active_circuits_ok_paranoid(chan); - goto done; - } -#endif - /* If n_flushed < max still, loop around and pick another circuit */ } @@ -2636,47 +2345,6 @@ assert_circuit_mux_okay(channel_t *chan) circuitmux_assert_okay(chan->cmux); } -#if 0 -/** Fail with an assert if the active circuits ring on orconn is - * corrupt. */ -void -assert_active_circuits_ok(channel_t *chan) -{ - circuit_t *head = NULL, *cur = NULL; - int n = 0; - - tor_assert(chan); - - cur = head = chan->active_circuits; - - if (! head) - return; - do { - circuit_t *next = *next_circ_on_chan_p(cur, chan); - circuit_t *prev = *prev_circ_on_chan_p(cur, chan); - cell_ewma_t *ewma; - tor_assert(next); - tor_assert(prev); - tor_assert(*next_circ_on_chan_p(prev, chan) == cur); - tor_assert(*prev_circ_on_chan_p(next, chan) == cur); - if (chan == cur->n_chan) { - ewma = &cur->n_cell_ewma; - tor_assert(!ewma->is_for_p_chan); - } else { - ewma = &TO_OR_CIRCUIT(cur)->p_cell_ewma; - tor_assert(ewma->is_for_p_chan); - } - tor_assert(ewma->heap_index != -1); - tor_assert(ewma == smartlist_get(chan->active_circuit_pqueue, - ewma->heap_index)); - n++; - cur = next; - } while (cur != head); - - tor_assert(n == smartlist_len(chan->active_circuit_pqueue)); -} -#endif - /** Return 1 if we shouldn't restart reading on this circuit, even if * we get a SENDME. Else return 0. */ diff --git a/src/or/relay.h b/src/or/relay.h index ef5074bbe..5759c5180 100644 --- a/src/or/relay.h +++ b/src/or/relay.h @@ -60,9 +60,6 @@ int append_address_to_payload(uint8_t *payload_out, const tor_addr_t *addr); const uint8_t *decode_address_from_payload(tor_addr_t *addr_out, const uint8_t *payload, int payload_len); -unsigned cell_ewma_get_tick(void); -void cell_ewma_set_scale_factor(const or_options_t *options, - const networkstatus_t *consensus); void circuit_clear_cell_queue(circuit_t *circ, channel_t *chan); #ifdef RELAY_PRIVATE -- cgit v1.2.3