| 
					
				 | 
			
			
				@@ -0,0 +1,93 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Copyright (c) 2003-2004, Roger Dingledine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright (c) 2007-2018, The Tor Project, Inc. */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* See LICENSE for licensing information */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "orconfig.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "lib/thread/numcpus.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "lib/log/torlog.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "lib/log/util_bug.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef HAVE_UNISTD_H 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <unistd.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef _WIN32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <windows.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <stdlib.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Implementation logic for compute_num_cpus(). */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+compute_num_cpus_impl(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef _WIN32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SYSTEM_INFO info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(&info, 0, sizeof(info)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GetSystemInfo(&info); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (info.dwNumberOfProcessors >= 1 && info.dwNumberOfProcessors < INT_MAX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (int)info.dwNumberOfProcessors; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#elif defined(HAVE_SYSCONF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef _SC_NPROCESSORS_CONF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long cpus_conf = sysconf(_SC_NPROCESSORS_CONF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long cpus_conf = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef _SC_NPROCESSORS_ONLN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long cpus_onln = sysconf(_SC_NPROCESSORS_ONLN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long cpus_onln = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  long cpus = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cpus_conf > 0 && cpus_onln < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cpus = cpus_conf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (cpus_onln > 0 && cpus_conf < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cpus = cpus_onln; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (cpus_onln > 0 && cpus_conf > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (cpus_onln < cpus_conf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_notice(LD_GENERAL, "I think we have %ld CPUS, but only %ld of them " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "are available. Telling Tor to only use %ld. You can over" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "ride this with the NumCPUs option", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 cpus_conf, cpus_onln, cpus_onln); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    cpus = cpus_onln; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (cpus >= 1 && cpus < INT_MAX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (int)cpus; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif /* defined(_WIN32) || ... */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define MAX_DETECTABLE_CPUS 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** Return how many CPUs we are running with.  We assume that nobody is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * using hot-swappable CPUs, so we don't recompute this after the first 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * time.  Return -1 if we don't know how to tell the number of CPUs on this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * system. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+compute_num_cpus(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  static int num_cpus = -2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (num_cpus == -2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    num_cpus = compute_num_cpus_impl(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tor_assert(num_cpus != -2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (num_cpus > MAX_DETECTABLE_CPUS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* LCOV_EXCL_START */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log_notice(LD_GENERAL, "Wow!  I detected that you have %d CPUs. I " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "will not autodetect any more than %d, though.  If you " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 "want to configure more, set NumCPUs in your torrc", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 num_cpus, MAX_DETECTABLE_CPUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      num_cpus = MAX_DETECTABLE_CPUS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /* LCOV_EXCL_STOP */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return num_cpus; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |