Tor 0.4.9.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(). */
26static 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_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 */
84int
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}
Headers for log.c.
#define LD_GENERAL
Definition: log.h:62
#define MAX_DETECTABLE_CPUS
Definition: numcpus.c:77
static int compute_num_cpus_impl(void)
Definition: numcpus.c:27
int compute_num_cpus(void)
Definition: numcpus.c:85
Header for numcpus.c.
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:103