/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License along with this program. If not, see . (c) 2011 Emanuele Oriani - ema at fastwebnet dot it */ #include #include #include #include static pid_t pid = -1; static int cpu = -1; static bool reset = false; static bool cpunum = false; // To get the number of available CPUs we run this // getaffinity BEFORE setting any affinity mask. // We will get all the available CPUs. static int num_cpus(void) { cpu_set_t cpu_set; CPU_ZERO(&cpu_set); const int max_cpus = 8*sizeof(cpu_set); if (0 == sched_getaffinity(getpid(), sizeof(cpu_set_t), &cpu_set)) { for(int i = 0; i < max_cpus; ++i) if (!CPU_ISSET(i, &cpu_set)) return i; } return max_cpus; } const int NCPUS = num_cpus(); static void usage(const char *img) { std::cerr << img << ", a simple program to set CPU affinity on Linux." << std::endl; std::cerr << "(c) 2011 Emanuele Oriani - ema at fastwebnet dot it" << std::endl; std::cerr << "\nUsage:" << std::endl; std::cerr << " " << img << " [-p pid] [-c cpu] [-r]" << std::endl; std::cerr << " p: specify a process pid" << std::endl; std::cerr << " c: specify a cpu id (0-n)" << std::endl; std::cerr << " r: reset (enable all cpus)" << std::endl; std::cerr << " g: print cpus number" << std::endl; } static void opts(int argc, char *argv[]) { extern char *optarg; int res = -1; while(EOF != (res = getopt(argc, argv, "p:c:rhg"))) { switch((char)res) { case 'p': pid = (pid_t)std::atoi(optarg); break; case 'c': cpu = std::atoi(optarg); break; case 'r': reset = true; break; case 'g': cpunum = true; break; case 'h': default: usage(argv[0]); std::exit(-2); break; } } } int main(int argc, char *argv[]) { opts(argc, argv); cpu_set_t cpu_set; if (cpunum) std::cout << "Available cpus: " << NCPUS << '.' << std::endl; if (-1 == pid) pid = getpid(); if (reset || (-1 != cpu)) { CPU_ZERO(&cpu_set); if (reset) { for(int i = 0; i < NCPUS; ++i) CPU_SET(i, &cpu_set); } else CPU_SET(cpu, &cpu_set); if (-1 == sched_setaffinity(pid, sizeof(cpu_set_t), &cpu_set)) { std::cerr << "Error : "; switch(errno) { case EFAULT: std::cerr << "A supplied memory address was invalid." << std::endl; std::exit(-1); break; case EINVAL: std::cerr << "The affinity bitmask mask contains no processors that are physically on the system, or cpusetsize is smaller than the size of the affinity mask used by the kernel." << std::endl; std::exit(-1); break; case EPERM: std::cerr << "The calling process does not have appropriate privileges." << std::endl; std::exit(-1); break; case ESRCH: std::cerr << "The process whose ID is " << pid << " could not be found." << std::endl; std::exit(-1); break; default: std::cerr << "Unknown error." << std::endl; std::exit(-1); break; } } } CPU_ZERO(&cpu_set); if (0 == sched_getaffinity(pid, sizeof(cpu_set_t), &cpu_set)) { std::cout << "Report:" << std::endl; for(int i = 0; i < NCPUS; ++i) if (CPU_ISSET(i, &cpu_set)) std::cout << "Cpu " << i << " is set." << std::endl; } }