1 // 2 // 3 // Copyright 2015 gRPC authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // 17 // 18 19 #ifndef _GNU_SOURCE 20 #define _GNU_SOURCE 21 #endif // _GNU_SOURCE 22 23 #include <grpc/support/port_platform.h> 24 25 #ifdef GPR_CPU_LINUX 26 27 #include <errno.h> 28 #include <grpc/support/cpu.h> 29 #include <grpc/support/sync.h> 30 #include <sched.h> 31 #include <string.h> 32 #include <unistd.h> 33 34 #include "absl/log/log.h" 35 #include "src/core/util/crash.h" 36 #include "src/core/util/strerror.h" 37 38 static int ncpus = 0; 39 init_num_cpus()40static void init_num_cpus() { 41 #ifndef GPR_MUSL_LIBC_COMPAT 42 if (sched_getcpu() < 0) { 43 LOG(ERROR) << "Error determining current CPU: " 44 << grpc_core::StrError(errno) << "\n"; 45 ncpus = 1; 46 return; 47 } 48 #endif 49 // This must be signed. sysconf returns -1 when the number cannot be 50 // determined 51 ncpus = static_cast<int>(sysconf(_SC_NPROCESSORS_CONF)); 52 if (ncpus < 1) { 53 LOG(ERROR) << "Cannot determine number of CPUs: assuming 1"; 54 ncpus = 1; 55 } 56 } 57 gpr_cpu_num_cores(void)58unsigned gpr_cpu_num_cores(void) { 59 static gpr_once once = GPR_ONCE_INIT; 60 gpr_once_init(&once, init_num_cpus); 61 return static_cast<unsigned>(ncpus); 62 } 63 gpr_cpu_current_cpu(void)64unsigned gpr_cpu_current_cpu(void) { 65 #ifdef GPR_MUSL_LIBC_COMPAT 66 // sched_getcpu() is undefined on musl 67 return 0; 68 #else 69 if (gpr_cpu_num_cores() == 1) { 70 return 0; 71 } 72 int cpu = sched_getcpu(); 73 if (cpu < 0) { 74 LOG(ERROR) << "Error determining current CPU: " 75 << grpc_core::StrError(errno) << "\n"; 76 return 0; 77 } 78 if (static_cast<unsigned>(cpu) >= gpr_cpu_num_cores()) { 79 VLOG(2) << "Cannot handle hot-plugged CPUs"; 80 return 0; 81 } 82 return static_cast<unsigned>(cpu); 83 #endif 84 } 85 86 #endif // GPR_CPU_LINUX 87