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 32static 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 42static 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 56static 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 83static 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; 97set_affinity: 98 return set_affinity(cpu); 99} 100 101#else 102static int set_affinity_single(void) 103{ 104 errno = ENOSYS; 105 return -1; 106} 107#endif 108