Tor  0.4.7.0-alpha-dev
numcpus.c
Go to the documentation of this file.
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
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_notice(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 #define MAX_DETECTABLE_CPUS 16
74 
75 /** Return how many CPUs we are running with. We assume that nobody is
76  * using hot-swappable CPUs, so we don't recompute this after the first
77  * time. Return -1 if we don't know how to tell the number of CPUs on this
78  * system.
79  */
80 int
82 {
83  static int num_cpus = -2;
84  if (num_cpus == -2) {
85  num_cpus = compute_num_cpus_impl();
86  tor_assert(num_cpus != -2);
87  if (num_cpus > MAX_DETECTABLE_CPUS) {
88  /* LCOV_EXCL_START */
89  log_notice(LD_GENERAL, "Wow! I detected that you have %d CPUs. I "
90  "will not autodetect any more than %d, though. If you "
91  "want to configure more, set NumCPUs in your torrc",
92  num_cpus, MAX_DETECTABLE_CPUS);
93  num_cpus = MAX_DETECTABLE_CPUS;
94  /* LCOV_EXCL_STOP */
95  }
96  }
97  return num_cpus;
98 }
Headers for log.c.
#define LD_GENERAL
Definition: log.h:62
static int compute_num_cpus_impl(void)
Definition: numcpus.c:27
int compute_num_cpus(void)
Definition: numcpus.c:81
Header for numcpus.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102