1 /* 2 * 3 * Copyright (c) Novell Inc. 2011 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms in version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 12 * the GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 * 18 * Author: Peter W. Morreale <pmorreale AT novell DOT com> 19 * Date: 11/08/2011 20 */ 21 22 /* 23 * Must be ported to OS's other than Linux 24 */ 25 26 #ifdef __linux__ 27 # define _GNU_SOURCE 28 # define AFFINITY_NEEDS_GNU_SOURCE 1 29 # include <sched.h> 30 # include <stdio.h> 31 32 static int set_affinity(int cpu) 33 { 34 cpu_set_t mask; 35 36 CPU_ZERO(&mask); 37 CPU_SET(cpu, &mask); 38 39 return (sched_setaffinity(0, sizeof(cpu_set_t), &mask)); 40 } 41 42 static int get_online_cpu_from_sysfs(void) 43 { 44 FILE *f; 45 int cpu = -1; 46 47 f = fopen("/sys/devices/system/cpu/online", "r"); 48 if (!f) 49 return -1; 50 fscanf(f, "%d", &cpu); 51 fclose(f); 52 53 return cpu; 54 } 55 56 static int get_online_cpu_from_cpuinfo(void) 57 { 58 FILE *f; 59 int cpu = -1; 60 char line[4096]; 61 62 f = fopen("/proc/cpuinfo", "r"); 63 if (!f) 64 return -1; 65 66 while (!feof(f)) { 67 if (!fgets(line, sizeof(line), f)) 68 return -1; 69 /* 70 * cpuinfo output is not consistent across all archictures, 71 * it can be "processor : N", but for example on s390 72 * it's: "processor N: ...", so ignore any non-number 73 * after "processor" 74 */ 75 if (sscanf(line, "processor%*[^0123456789]%d", &cpu) == 1) 76 break; 77 } 78 fclose(f); 79 80 return cpu; 81 } 82 83 static int set_affinity_single(void) 84 { 85 int cpu; 86 87 cpu = get_online_cpu_from_sysfs(); 88 if (cpu >= 0) 89 goto set_affinity; 90 91 cpu = get_online_cpu_from_cpuinfo(); 92 if (cpu >= 0) 93 goto set_affinity; 94 95 fprintf(stderr, "WARNING: Failed to detect online cpu, using cpu=0\n"); 96 cpu = 0; 97 set_affinity: 98 return set_affinity(cpu); 99 } 100 101 #else 102 static int set_affinity_single(void) 103 { 104 errno = ENOSYS; 105 return -1; 106 } 107 #endif 108