[tor-commits] [tor/master] Implement circuitmux_alloc()/circuitmux_free() and chanid/circid->muxinfo hash table

andrea at torproject.org andrea at torproject.org
Thu Oct 11 02:05:23 UTC 2012


commit e4a11b890e7c5fe45dc1f5f271fbd8130ccc9c55
Author: Andrea Shepard <andrea at torproject.org>
Date:   Mon Sep 24 08:52:05 2012 -0700

    Implement circuitmux_alloc()/circuitmux_free() and chanid/circid->muxinfo hash table
---
 src/or/circuitmux.c |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 143 insertions(+), 1 deletions(-)

diff --git a/src/or/circuitmux.c b/src/or/circuitmux.c
index 45b72f2..d4866ca 100644
--- a/src/or/circuitmux.c
+++ b/src/or/circuitmux.c
@@ -10,6 +10,33 @@
 #include "circuitmux.h"
 
 /*
+ * Private typedefs for circuitmux.c
+ */
+
+/*
+ * Map of muxinfos for circuitmux_t to use; struct is defined below (name
+ * of struct must match HT_HEAD line).
+ */
+typedef struct chanid_circid_muxinfo_map chanid_circid_muxinfo_map_t;
+
+/*
+ * Hash table entry (yeah, calling it chanid_circid_muxinfo_s seems to
+ * break the hash table code).
+ */
+typedef struct chanid_circid_muxinfo_t chanid_circid_muxinfo_t;
+
+/*
+ * Anything the mux wants to store per-circuit in the map; right now just
+ * a count of queued cells.
+ */
+
+typedef struct circuit_muxinfo_s circuit_muxinfo_t;
+
+/*
+ * Structures for circuitmux.c
+ */
+
+/*
  * A circuitmux is a collection of circuits; it tracks which subset
  * of the attached circuits are 'active' (i.e., have cells available
  * to transmit) and how many cells on each.  It expoes three distinct
@@ -40,6 +67,14 @@
  */
 
 struct circuitmux_s {
+  /* Keep count of attached, active circuits */
+  unsigned int n_circuits, n_active_circuits;
+
+  /*
+   * Map from (channel ID, circuit ID) pairs to circuit_muxinfo_t
+   */
+  chanid_circid_muxinfo_map_t *chanid_circid_map;
+
   /*
    * Double-linked ring of circuits with queued cells waiting for room to
    * free up on this connection's outbuf.  Every time we pull cells from
@@ -62,6 +97,113 @@ struct circuitmux_s {
    * The tick on which the cell_ewma_ts in active_circuit_pqueue last had
    * their ewma values rescaled.
    */
-  unsigned active_circuit_pqueue_last_recalibrated;
+  unsigned int active_circuit_pqueue_last_recalibrated;
+};
+
+/*
+ * This struct holds whatever we want to store per attached circuit on a
+ * circuitmux_t; right now, just the count of queued cells.
+ */
+
+struct circuit_muxinfo_s {
+  unsigned int cell_count;
+};
+
+/*
+ * A map from channel ID and circuit ID to a circuit_muxinfo_t for that
+ * circuit.
+ */
+
+struct chanid_circid_muxinfo_t {
+  HT_ENTRY(chanid_circid_muxinfo_t) node;
+  uint64_t chan_id;
+  circid_t circ_id;
+  circuit_muxinfo_t muxinfo;
 };
 
+/*
+ * Static function declarations
+ */
+
+static INLINE int
+chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
+                         chanid_circid_muxinfo_t *b);
+static INLINE unsigned int
+chanid_circid_entry_hash(chanid_circid_muxinfo_t *a);
+
+/* Function definitions */
+
+/**
+ * Helper for chanid_circid_cell_count_map_t hash table: compare the channel
+ * ID and circuit ID for a and b, and return less than, equal to, or greater
+ * than zero appropriately.
+ */
+
+static INLINE int
+chanid_circid_entries_eq(chanid_circid_muxinfo_t *a,
+                         chanid_circid_muxinfo_t *b)
+{
+    return a->chan_id == b->chan_id && a->circ_id == b->circ_id;
+}
+
+/**
+ * Helper: return a hash based on circuit ID and channel ID in a.
+ */
+
+static INLINE unsigned int
+chanid_circid_entry_hash(chanid_circid_muxinfo_t *a)
+{
+    return (((unsigned int)(a->circ_id) << 8) ^
+            ((unsigned int)((a->chan_id >> 32) & 0xffffffff)) ^
+            ((unsigned int)(a->chan_id & 0xffffffff)));
+}
+
+/* Declare the struct chanid_circid_muxinfo_map type */
+HT_HEAD(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t);
+
+/* Emit a bunch of hash table stuff */
+HT_PROTOTYPE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
+             chanid_circid_entry_hash, chanid_circid_entries_eq);
+HT_GENERATE(chanid_circid_muxinfo_map, chanid_circid_muxinfo_t, node,
+            chanid_circid_entry_hash, chanid_circid_entries_eq, 0.6,
+            malloc, realloc, free);
+
+/**
+ * Allocate a new circuitmux_t
+ */
+
+circuitmux_t *
+circuitmux_alloc(void)
+{
+  circuitmux_t *rv = NULL;
+
+  rv = tor_malloc_zero(sizeof(*rv));
+  rv->chanid_circid_map = tor_malloc_zero(sizeof(*( rv->chanid_circid_map)));
+  HT_INIT(chanid_circid_muxinfo_map, rv->chanid_circid_map);
+
+  return rv;
+}
+
+/**
+ * Free a circuitmux_t; the circuits must be detached first with
+ * circuitmux_detach_all_circuits().
+ */
+
+void
+circuitmux_free(circuitmux_t *cmux)
+{
+  if (!cmux) return;
+
+  tor_assert(cmux->n_circuits == 0);
+  tor_assert(cmux->n_active_circuits == 0);
+
+  smartlist_free(cmux->active_circuit_pqueue);
+
+  if (cmux->chanid_circid_map) {
+    HT_CLEAR(chanid_circid_muxinfo_map, cmux->chanid_circid_map);
+    tor_free(cmux->chanid_circid_map);
+  }
+
+  tor_free(cmux);
+}
+





More information about the tor-commits mailing list