blob: 503a96b4c8a0a29bcbe374c49dc6ef36d4fd16d9 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080016 *
17 */
18
ctillerd94ad102014-12-23 08:53:43 -080019#include <grpc/support/port_platform.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080020
ctillerd94ad102014-12-23 08:53:43 -080021#ifdef GPR_CPU_POSIX
22
nnoble0c475f02014-12-05 15:37:39 -080023#include <errno.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080024#include <string.h>
Craig Tillerf40df232016-03-25 13:38:14 -070025#include <unistd.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080026
Yash Tibrewal547653e2017-09-25 21:20:19 -070027#include <grpc/support/cpu.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080028#include <grpc/support/log.h>
Craig Tillerb5a79f62015-02-24 21:02:51 -080029#include <grpc/support/sync.h>
yang-g6955c5e2017-02-13 15:49:27 -080030#include <grpc/support/useful.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080031
Jorge Canizales30e666c2015-03-13 14:45:40 -070032static __thread char magic_thread_local;
33
Craig Tillerebc7ef22015-09-10 22:19:25 -070034static long ncpus = 0;
Nicolas Noble085603c2015-02-24 13:29:29 -080035
36static void init_ncpus() {
37 ncpus = sysconf(_SC_NPROCESSORS_ONLN);
Jan Tattermuschf423b062016-01-19 19:16:36 -080038 if (ncpus < 1 || ncpus > INT32_MAX) {
Nicolas Noble085603c2015-02-24 13:29:29 -080039 gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
40 ncpus = 1;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080041 }
Nicolas Noble085603c2015-02-24 13:29:29 -080042}
43
44unsigned gpr_cpu_num_cores(void) {
45 static gpr_once once = GPR_ONCE_INIT;
Craig Tillerb5a79f62015-02-24 21:02:51 -080046 gpr_once_init(&once, init_ncpus);
Craig Tillerebc7ef22015-09-10 22:19:25 -070047 return (unsigned)ncpus;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080048}
49
Jorge Canizales30e666c2015-03-13 14:45:40 -070050unsigned gpr_cpu_current_cpu(void) {
51 /* NOTE: there's no way I know to return the actual cpu index portably...
52 most code that's using this is using it to shard across work queues though,
53 so here we use thread identity instead to achieve a similar though not
54 identical effect */
yang-g6955c5e2017-02-13 15:49:27 -080055 return (unsigned)GPR_HASH_POINTER(&magic_thread_local, gpr_cpu_num_cores());
Jorge Canizales30e666c2015-03-13 14:45:40 -070056}
57
58#endif /* GPR_CPU_POSIX */