tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

numcpus.c (2891B)


      1 /* Copyright (c) 2003-2004, Roger Dingledine
      2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      3 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      4 /* See LICENSE for licensing information */
      5 
      6 /**
      7 * \file numcpus.c
      8 * \brief Compute the number of CPUs configured on this system.
      9 **/
     10 
     11 #include "orconfig.h"
     12 #include "lib/thread/numcpus.h"
     13 #include "lib/log/log.h"
     14 #include "lib/log/util_bug.h"
     15 
     16 #ifdef HAVE_UNISTD_H
     17 #include <unistd.h>
     18 #endif
     19 #ifdef _WIN32
     20 #include <windows.h>
     21 #endif
     22 
     23 #include <stdlib.h>
     24 
     25 /** Implementation logic for compute_num_cpus(). */
     26 static int
     27 compute_num_cpus_impl(void)
     28 {
     29 #ifdef _WIN32
     30  SYSTEM_INFO info;
     31  memset(&info, 0, sizeof(info));
     32  GetSystemInfo(&info);
     33  if (info.dwNumberOfProcessors >= 1 && info.dwNumberOfProcessors < INT_MAX)
     34    return (int)info.dwNumberOfProcessors;
     35  else
     36    return -1;
     37 #elif defined(HAVE_SYSCONF)
     38 #ifdef _SC_NPROCESSORS_CONF
     39  long cpus_conf = sysconf(_SC_NPROCESSORS_CONF);
     40 #else
     41  long cpus_conf = -1;
     42 #endif
     43 #ifdef _SC_NPROCESSORS_ONLN
     44  long cpus_onln = sysconf(_SC_NPROCESSORS_ONLN);
     45 #else
     46  long cpus_onln = -1;
     47 #endif
     48  long cpus = -1;
     49 
     50  if (cpus_conf > 0 && cpus_onln < 0) {
     51    cpus = cpus_conf;
     52  } else if (cpus_onln > 0 && cpus_conf < 0) {
     53    cpus = cpus_onln;
     54  } else if (cpus_onln > 0 && cpus_conf > 0) {
     55    if (cpus_onln < cpus_conf) {
     56      log_info(LD_GENERAL, "I think we have %ld CPUS, but only %ld of them "
     57               "are available. Telling Tor to only use %ld. You can over"
     58               "ride this with the NumCPUs option",
     59               cpus_conf, cpus_onln, cpus_onln);
     60    }
     61    cpus = cpus_onln;
     62  }
     63 
     64  if (cpus >= 1 && cpus < INT_MAX)
     65    return (int)cpus;
     66  else
     67    return -1;
     68 #else
     69  return -1;
     70 #endif /* defined(_WIN32) || ... */
     71 }
     72 
     73 /** This is an arbitrary number but at this point in time, it is not that
     74 * uncommon to see servers up to that amount of CPUs. Most servers will likely
     75 * be around 16 to 32 cores now. Lets take advantage of large machines! The
     76 * "NumCPUs" torrc option overrides this maximum. */
     77 #define MAX_DETECTABLE_CPUS 128
     78 
     79 /** Return how many CPUs we are running with.  We assume that nobody is
     80 * using hot-swappable CPUs, so we don't recompute this after the first
     81 * time.  Return -1 if we don't know how to tell the number of CPUs on this
     82 * system.
     83 */
     84 int
     85 compute_num_cpus(void)
     86 {
     87  static int num_cpus = -2;
     88  if (num_cpus == -2) {
     89    num_cpus = compute_num_cpus_impl();
     90    tor_assert(num_cpus != -2);
     91    if (num_cpus > MAX_DETECTABLE_CPUS) {
     92      /* LCOV_EXCL_START */
     93      log_notice(LD_GENERAL, "Wow!  I detected that you have %d CPUs. I "
     94                 "will not autodetect any more than %d, though.  If you "
     95                 "want to configure more, set NumCPUs in your torrc",
     96                 num_cpus, MAX_DETECTABLE_CPUS);
     97      num_cpus = MAX_DETECTABLE_CPUS;
     98      /* LCOV_EXCL_STOP */
     99    }
    100  }
    101  return num_cpus;
    102 }