commit 5b55e0e18180d96331e846b700ac194e24f43b8e Merge: a73b0da 3133cde Author: Nick Mathewson nickm@torproject.org Date: Mon Feb 10 15:04:23 2014 -0500
Merge remote-tracking branch 'public/no_itime_queue'
The conflicts here were tricky, and required me to eliminate the command-queue as well. That wasn't so hard.
Conflicts: src/or/or.h src/or/relay.c
changes/bug10870 | 6 ++ src/or/or.h | 36 ---------- src/or/relay.c | 205 ++++++++++-------------------------------------------- 3 files changed, 43 insertions(+), 204 deletions(-)
diff --cc src/or/or.h index b63b1ff,3eaf344..15cda28 --- a/src/or/or.h +++ b/src/or/or.h @@@ -1124,45 -1084,9 +1124,9 @@@ typedef struct packed_cell_t /** A queue of cells on a circuit, waiting to be added to the * or_connection_t's outbuf. */ typedef struct cell_queue_t { - packed_cell_t *head; /**< The first cell, or NULL if the queue is empty. */ - packed_cell_t *tail; /**< The last cell, or NULL if the queue is empty. */ + /** Linked list of packed_cell_t*/ + TOR_SIMPLEQ_HEAD(cell_simpleq, packed_cell_t) head; int n; /**< The number of cells in the queue. */ - insertion_time_queue_t *insertion_times; /**< Insertion times of cells. */ - /** Commands of inserted cells. */ - insertion_command_queue_t *insertion_commands; } cell_queue_t;
/** Beginning of a RELAY cell payload. */ diff --cc src/or/relay.c index b5e4ff7,6e5b12e..94016b4 --- a/src/or/relay.c +++ b/src/or/relay.c @@@ -2153,68 -2136,13 +2137,20 @@@ cell_queue_append(cell_queue_t *queue, ++queue->n; }
- /** Append command of type <b>command</b> in direction to <b>queue</b> for - * CELL_STATS event. */ - static void - cell_command_queue_append(cell_queue_t *queue, uint8_t command) - { - insertion_command_queue_t *ic_queue = queue->insertion_commands; - if (!ic_pool) - ic_pool = mp_pool_new(sizeof(insertion_command_elem_t), 1024); - if (!ic_queue) { - ic_queue = tor_malloc_zero(sizeof(insertion_command_queue_t)); - queue->insertion_commands = ic_queue; - } - if (ic_queue->last && ic_queue->last->command == command) { - ic_queue->last->counter++; - } else { - insertion_command_elem_t *elem = mp_pool_get(ic_pool); - elem->next = NULL; - elem->command = command; - elem->counter = 1; - if (ic_queue->last) { - ic_queue->last->next = elem; - ic_queue->last = elem; - } else { - ic_queue->first = ic_queue->last = elem; - } - } - } - - /** Retrieve oldest command from <b>queue</b> and write it to - * <b>command</b> for CELL_STATS event. Return 0 for success, -1 - * otherwise. */ - static int - cell_command_queue_pop(uint8_t *command, cell_queue_t *queue) - { - int res = -1; - insertion_command_queue_t *ic_queue = queue->insertion_commands; - if (ic_queue && ic_queue->first) { - insertion_command_elem_t *ic_elem = ic_queue->first; - ic_elem->counter--; - if (ic_elem->counter < 1) { - ic_queue->first = ic_elem->next; - if (ic_elem == ic_queue->last) - ic_queue->last = NULL; - mp_pool_release(ic_elem); - } - *command = ic_elem->command; - res = 0; - } - return res; - } - -/** Append a newly allocated copy of <b>cell</b> to the end of <b>queue</b> */ +/** Append a newly allocated copy of <b>cell</b> to the end of the + * <b>exitward</b> (or app-ward) <b>queue</b> of <b>circ</b>. If + * <b>use_stats</b> is true, record statistics about the cell. + */ void -cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell, - int wide_circ_ids) +cell_queue_append_packed_copy(circuit_t *circ, cell_queue_t *queue, + int exitward, const cell_t *cell, + int wide_circ_ids, int use_stats) { struct timeval now; packed_cell_t *copy = packed_cell_copy(cell, wide_circ_ids); ++ (void)circ; ++ (void)exitward; ++ (void)use_stats; tor_gettimeofday_cached(&now); copy->inserted_time = (uint32_t)tv_to_msec(&now);
@@@ -2276,21 -2153,15 +2169,13 @@@ cell_queue_init(cell_queue_t *queue void cell_queue_clear(cell_queue_t *queue) { - packed_cell_t *cell, *next; - cell = queue->head; - while (cell) { - next = cell->next; + packed_cell_t *cell; + while ((cell = TOR_SIMPLEQ_FIRST(&queue->head))) { + TOR_SIMPLEQ_REMOVE_HEAD(&queue->head, next); packed_cell_free_unchecked(cell); - cell = next; } - queue->head = queue->tail = NULL; + TOR_SIMPLEQ_INIT(&queue->head); queue->n = 0; - if (queue->insertion_times) { - while (queue->insertion_times->first) { - insertion_time_elem_t *elem = queue->insertion_times->first; - queue->insertion_times->first = elem->next; - mp_pool_release(elem); - } - tor_free(queue->insertion_times); - } }
/** Extract and return the cell at the head of <b>queue</b>; return NULL if @@@ -2443,6 -2316,6 +2326,17 @@@ set_streams_blocked_on_circ(circuit_t * return n; }
++/** Extract the command from a packed cell. */ ++static uint8_t ++packed_cell_get_command(const packed_cell_t *cell, int wide_circ_ids) ++{ ++ if (wide_circ_ids) { ++ return get_uint8(cell->body+4); ++ } else { ++ return get_uint8(cell->body+2); ++ } ++} ++ /** Pull as many cells as possible (but no more than <b>max</b>) from the * queue of the first active circuit on <b>chan</b>, and write them to * <b>chan</b>->outbuf. Return the number of cells written. Advance @@@ -2502,58 -2364,15 +2396,33 @@@ channel_flush_from_first_active_circuit cell = cell_queue_pop(queue);
/* Calculate the exact time that this cell has spent in the queue. */ - if (get_options()->CellStatistics && !CIRCUIT_IS_ORIGIN(circ)) { + if (get_options()->CellStatistics || + get_options()->TestingEnableCellStatsEvent) { + uint32_t msec_waiting; struct timeval tvnow; - uint32_t flushed; - uint32_t cell_waiting_time; - insertion_time_queue_t *it_queue = queue->insertion_times; - or_circ = TO_OR_CIRCUIT(circ); tor_gettimeofday_cached(&tvnow); - flushed = (uint32_t)((tvnow.tv_sec % SECONDS_IN_A_DAY) * 100L + - (uint32_t)tvnow.tv_usec / (uint32_t)10000L); - if (!it_queue || !it_queue->first) { - log_info(LD_GENERAL, "Cannot determine insertion time of cell. " - "Looks like the CellStatistics option was " - "recently enabled."); - } else { - insertion_time_elem_t *elem = it_queue->first; - cell_waiting_time = - (uint32_t)((flushed * 10L + SECONDS_IN_A_DAY * 1000L - - elem->insertion_time * 10L) % - (SECONDS_IN_A_DAY * 1000L)); - #undef SECONDS_IN_A_DAY - elem->counter--; - if (elem->counter < 1) { - it_queue->first = elem->next; - if (elem == it_queue->last) - it_queue->last = NULL; - mp_pool_release(elem); - } - if (get_options()->CellStatistics && !CIRCUIT_IS_ORIGIN(circ)) { - or_circ = TO_OR_CIRCUIT(circ); - or_circ->total_cell_waiting_time += cell_waiting_time; - or_circ->processed_cells++; - } - if (get_options()->TestingEnableCellStatsEvent) { - uint8_t command; - if (cell_command_queue_pop(&command, queue) < 0) { - log_info(LD_GENERAL, "Cannot determine command of cell. " - "Looks like the CELL_STATS event was " - "recently enabled."); - } else { - testing_cell_stats_entry_t *ent = - tor_malloc_zero(sizeof(testing_cell_stats_entry_t)); - ent->command = command; - ent->waiting_time = (unsigned int)cell_waiting_time / 10; - ent->removed = 1; - if (circ->n_chan == chan) - ent->exitward = 1; - if (!circ->testing_cell_stats) - circ->testing_cell_stats = smartlist_new(); - smartlist_add(circ->testing_cell_stats, ent); - } - } + msec_waiting = ((uint32_t)tv_to_msec(&tvnow)) - cell->inserted_time; + - or_circ->total_cell_waiting_time += msec_waiting; - or_circ->processed_cells++; ++ if (get_options()->CellStatistics && !CIRCUIT_IS_ORIGIN(circ)) { ++ or_circ = TO_OR_CIRCUIT(circ); ++ or_circ->total_cell_waiting_time += msec_waiting; ++ or_circ->processed_cells++; ++ } ++ ++ if (get_options()->TestingEnableCellStatsEvent) { ++ uint8_t command = packed_cell_get_command(cell, chan->wide_circ_ids); ++ ++ testing_cell_stats_entry_t *ent = ++ tor_malloc_zero(sizeof(testing_cell_stats_entry_t)); ++ ent->command = command; ++ ent->waiting_time = msec_waiting / 10; ++ ent->removed = 1; ++ if (circ->n_chan == chan) ++ ent->exitward = 1; ++ if (!circ->testing_cell_stats) ++ circ->testing_cell_stats = smartlist_new(); ++ smartlist_add(circ->testing_cell_stats, ent); + } }
/* If we just flushed our queue and this circuit is used for a
tor-commits@lists.torproject.org