/*********************************************************************** * GNU Lesser General Public License * * This file is part of the GFDL Flexible Modeling System (FMS). * * FMS is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or (at * your option) any later version. * * FMS is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FMS. If not, see . **********************************************************************/ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #ifndef __APPLE__ static pid_t gettid(void) { return syscall(__NR_gettid); } #endif /* * Returns this thread's CPU affinity, if bound to a single core, * or else -1. */ int get_cpu_affinity(void) { #ifndef __APPLE__ cpu_set_t coremask; /* core affinity mask */ CPU_ZERO(&coremask); if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { fprintf(stderr,"Unable to get thread %d affinity. %s\n",gettid(),strerror(errno)); } int cpu; for (cpu=0;cpu < CPU_SETSIZE;cpu++) { if (CPU_ISSET(cpu,&coremask)) { return cpu; } } #endif return -1; } int get_cpu_affinity_(void) { return get_cpu_affinity(); } /* Fortran interface */ /* * Returns this groups CPUSET * and also the CPUSET size or -1 (in case of a storage error) */ int get_cpuset(int fsz, int *output, int pe, _Bool debug) { #ifndef __APPLE__ cpu_set_t coremask; /* core affinity mask */ CPU_ZERO(&coremask); if (sched_getaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { fprintf(stderr,"Unable to get thread %d affinity. %s\n",gettid(),strerror(errno)); } int cpu; int count; if (debug) { for (cpu=0;cpu < CPU_SETSIZE;cpu++) { if (CPU_ISSET(cpu,&coremask)) { printf("=> get_cpuset - pe %d: %d\n",pe, cpu); } } } count = 0; for (cpu=0;cpu < CPU_SETSIZE;cpu++) { if (CPU_ISSET(cpu,&coremask)) { if (count > fsz) { return -1; } output[count] = cpu; count ++; } } return count; #else return fsz; #endif } int get_cpuset_(int *fsz, int *output, int *pe, _Bool *debug) { return get_cpuset(*fsz, output, *pe, *debug); } /* Fortran interface */ /* * Set CPU affinity to one core. */ int set_cpu_affinity(int cpu) { #ifndef __APPLE__ cpu_set_t coremask; /* core affinity mask */ CPU_ZERO(&coremask); CPU_SET(cpu,&coremask); if (sched_setaffinity(gettid(),sizeof(cpu_set_t),&coremask) != 0) { return -1; } #endif return 0; } int set_cpu_affinity_(int *cpu) { return set_cpu_affinity(*cpu); } /* Fortran interface */