return mdiff;
}
++/**
++ * Converts timeval to milliseconds.
++ */
++int64_t
++tv_to_msec(const struct timeval *tv)
++{
++ int64_t conv = ((int64_t)tv->tv_sec)*1000L;
++ /* Round ghetto-style */
++ conv += ((int64_t)tv->tv_usec+500)/1000L;
++ return conv;
++}
++
/** Yield true iff <b>y</b> is a leap-year. */
#define IS_LEAPYEAR(y) (!(y % 4) && ((y % 100) || !(y % 400)))
/** Helper: Return the number of leap-days between Jan 1, y1 and Jan 1, y2. */
int base16_decode(char *dest, size_t destlen, const char *src, size_t srclen);
/* Time helpers */
-double tv_to_double(const struct timeval *tv);
-int64_t tv_to_msec(const struct timeval *tv);
-int64_t tv_to_usec(const struct timeval *tv);
long tv_udiff(const struct timeval *start, const struct timeval *end);
long tv_mdiff(const struct timeval *start, const struct timeval *end);
++int64_t tv_to_msec(const struct timeval *tv);
int tor_timegm(const struct tm *tm, time_t *time_out);
#define RFC1123_TIME_LEN 29
void format_rfc1123_time(char *buf, time_t t);
return n;
}
- /** helper to sort a list of circuit_q by total queue lengths, in descending
- * order. */
+ /**
+ * Return the age of the oldest cell queued on <b>c</b>, in milliseconds.
+ * Return 0 if there are no cells queued on c. Requires that <b>now</b> be
+ * the current time in milliseconds since the epoch, truncated.
+ *
+ * This function will return incorrect results if the oldest cell queued on
+ * the circuit is older than 2**32 msec (about 49 days) old.
+ */
+ static uint32_t
+ circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
+ {
+ uint32_t age = 0;
- if (c->n_conn_cells.head)
- age = now - c->n_conn_cells.head->inserted_time;
++ if (c->n_chan_cells.head)
++ age = now - c->n_chan_cells.head->inserted_time;
+
+ if (! CIRCUIT_IS_ORIGIN(c)) {
+ const or_circuit_t *orcirc = TO_OR_CIRCUIT((circuit_t*)c);
- if (orcirc->p_conn_cells.head) {
- uint32_t age2 = now - orcirc->p_conn_cells.head->inserted_time;
++ if (orcirc->p_chan_cells.head) {
++ uint32_t age2 = now - orcirc->p_chan_cells.head->inserted_time;
+ if (age2 > age)
+ return age2;
+ }
+ }
+ return age;
+ }
+
+ /** Temporary variable for circuits_compare_by_oldest_queued_cell_ This is a
+ * kludge to work around the fact that qsort doesn't provide a way for
+ * comparison functions to take an extra argument. */
+ static uint32_t circcomp_now_tmp;
+
+ /** Helper to sort a list of circuit_t by age of oldest cell, in descending
+ * order. Requires that circcomp_now_tmp is set correctly. */
static int
- circuits_compare_by_queue_len_(const void **a_, const void **b_)
+ circuits_compare_by_oldest_queued_cell_(const void **a_, const void **b_)
{
const circuit_t *a = *a_;
const circuit_t *b = *b_;
/** A cell as packed for writing to the network. */
typedef struct packed_cell_t {
struct packed_cell_t *next; /**< Next cell queued on this circuit. */
- char body[CELL_NETWORK_SIZE]; /**< Cell as packed for network. */
+ char body[CELL_MAX_NETWORK_SIZE]; /**< Cell as packed for network. */
+ uint32_t inserted_time; /**< Time (in milliseconds since epoch, with high
+ * bits truncated) when this cell was inserted. */
} packed_cell_t;
+ /* XXXX This next structure may be obsoleted by inserted_time in
+ * packed_cell_t */
+
/** Number of cells added to a circuit queue including their insertion
* time on 10 millisecond detail; used for buffer statistics. */
typedef struct insertion_time_elem_t {
/** Append a newly allocated copy of <b>cell</b> to the end of <b>queue</b> */
void
-cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell)
+cell_queue_append_packed_copy(cell_queue_t *queue, const cell_t *cell,
+ int wide_circ_ids)
{
- packed_cell_t *copy = packed_cell_copy(cell);
+ struct timeval now;
+ packed_cell_t *copy = packed_cell_copy(cell, wide_circ_ids);
+ tor_gettimeofday_cached(&now);
+ copy->inserted_time = (uint32_t)tv_to_msec(&now);
+
/* Remember the time when this cell was put in the queue. */
+ /*XXXX This may be obsoleted by inserted_time */
if (get_options()->CellStatistics) {
- struct timeval now;
uint32_t added;
insertion_time_queue_t *it_queue = queue->insertion_times;
if (!it_pool)