FV3 Bundle
affinity.c
Go to the documentation of this file.
1 /***********************************************************************
2  * GNU Lesser General Public License
3  *
4  * This file is part of the GFDL Flexible Modeling System (FMS).
5  *
6  * FMS is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or (at
9  * your option) any later version.
10  *
11  * FMS is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18  **********************************************************************/
19 #define _GNU_SOURCE
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25 #include <sched.h>
26 #include <errno.h>
27 #include <sys/resource.h>
28 #include <sys/syscall.h>
29 
30 static pid_t gettid(void)
31 {
32 #ifdef __APPLE__
33  return syscall(SYS_gettid);
34 #else
35  return syscall(__NR_gettid);
36 #endif
37 }
38 
39 #ifndef __APPLE__
40 /*
41  * Returns this thread's CPU affinity, if bound to a single core,
42  * or else -1.
43  */
45 {
46  cpu_set_t coremask; /* core affinity mask */
47 
48  CPU_ZERO(&coremask);
49  if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
50  fprintf(stderr,"Unable to get thread %d affinity. %s\n",gettid(),strerror(errno));
51  }
52 
53  int cpu;
54  int first_cpu = -1; /* first CPU in range */
55  int last_cpu = -1; /* last CPU in range */
56  for (cpu=0;cpu < CPU_SETSIZE;cpu++) {
57  if (CPU_ISSET(cpu,&coremask)) {
58  if (first_cpu == -1) {
59  first_cpu = cpu;
60  } else {
61  last_cpu = cpu;
62  }
63  }
64  }
65 
66  if (last_cpu != -1) {return (first_cpu);}
67  return (last_cpu == -1) ? first_cpu : -1;
68 }
69 
70 int get_cpu_affinity_(void) { return get_cpu_affinity(); } /* Fortran interface */
71 
72 
73 /*
74  * Set CPU affinity to one core.
75  */
76 void set_cpu_affinity( int cpu )
77 {
78  cpu_set_t coremask; /* core affinity mask */
79 
80  CPU_ZERO(&coremask);
81  CPU_SET(cpu,&coremask);
82  if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) {
83  fprintf(stderr,"Unable to set thread %d affinity. %s\n",gettid(),strerror(errno));
84  }
85 }
86 
87 void set_cpu_affinity_(int *cpu) { set_cpu_affinity(*cpu); } /* Fortran interface */
88 #endif
void set_cpu_affinity_(int *cpu)
Definition: affinity.c:87
int get_cpu_affinity_(void)
Definition: affinity.c:70
static pid_t gettid(void)
Definition: affinity.c:30
int get_cpu_affinity(void)
Definition: affinity.c:44
void set_cpu_affinity(int cpu)
Definition: affinity.c:76