Browse Source

Set the number of additional eventloops in the torrc

You can now set the number of additional eventloops (and therefore
threads) to use with the 'NumAdditionalEventloops' option in the
torrc.

If set to 0 (the default), tor will add relay connection events to
the main eventloop. Otherwise, tor will add relay connection
events to one of the additional eventloops (but never to the main
eventloop).
Steven Engler 4 years ago
parent
commit
58d6ee9fc0
3 changed files with 24 additions and 5 deletions
  1. 10 2
      src/app/config/config.c
  2. 2 0
      src/app/config/or_options_st.h
  3. 12 3
      src/core/mainloop/mainloop.c

+ 10 - 2
src/app/config/config.c

@@ -759,6 +759,7 @@ static const config_var_t option_vars_[] = {
   V(TestingDirAuthVoteHSDirIsStrict,  BOOL,     "0"),
   VAR_INVIS("___UsingTestNetworkDefaults", BOOL, UsingTestNetworkDefaults_,
             "0"),
+  V(NumAdditionalEventloops, POSINT, 0),
 
   END_OF_CONFIG_VARS
 };
@@ -7991,8 +7992,15 @@ init_libevent(const or_options_t *options)
   cfg.num_cpus = get_num_cpus(options);
   cfg.msec_per_tick = options->TokenBucketRefillInterval;
 
-  /* Don't use any additional eventloops (only use the mainloop). */
-  int num_additional_eventloops = 2;
+  int num_additional_eventloops = options->NumAdditionalEventloops;
+  int max = 16; // this is an arbitrary but sane limit
+
+  if (num_additional_eventloops > max) {
+    log_warn(LD_CONFIG, "Set to use %d additional eventloops, but limiting "
+                        "to only %d.",
+             num_additional_eventloops, max);
+    num_additional_eventloops = max;
+  }
 
   tor_libevent_initialize(&cfg, num_additional_eventloops);
   log_info(LD_CONFIG, "Initializing libevent with %d additional eventloops.",

+ 2 - 0
src/app/config/or_options_st.h

@@ -1109,6 +1109,8 @@ struct or_options_t {
    **/
   int DormantCanceledByStartup;
 
+  int NumAdditionalEventloops;
+
   /**
    * Configuration objects for individual modules.
    *

+ 12 - 3
src/core/mainloop/mainloop.c

@@ -284,10 +284,19 @@ connection_add_impl(connection_t *conn, int is_connecting)
   } else {
     tor_assert(conn->type == CONN_TYPE_OR);
 
-    int eventloop_index = 1 + (eventloop_counter%(get_num_eventloops()-1));
+    int eventloop_index;
+    int num_eventloops = get_num_eventloops();
+
+    if (num_eventloops > 1) {
+      // use one of the worker threads
+      eventloop_index = 1 + (eventloop_counter%(num_eventloops-1));
+      eventloop_counter += 1;
+    } else {
+      // use the main thread
+      eventloop_index = 0;
+    }
+
     struct event_base *base = get_eventloop(eventloop_index);
-    eventloop_counter += 1;
-    //struct event_base *base = tor_libevent_get_base();
     error_t rv = safe_connection_register_events(conn->safe_conn, base);
 
     if (rv != E_SUCCESS) {