0001
0002
0003 #define _GNU_SOURCE 1
0004 #include <sched.h>
0005 #include <stdlib.h>
0006 #include <linux/bitmap.h>
0007 #include <linux/zalloc.h>
0008 #include "perf.h"
0009 #include "cpumap.h"
0010 #include "affinity.h"
0011
0012 static int get_cpu_set_size(void)
0013 {
0014 int sz = cpu__max_cpu().cpu + 8 - 1;
0015
0016
0017
0018
0019 if (sz < 4096)
0020 sz = 4096;
0021 return sz / 8;
0022 }
0023
0024 int affinity__setup(struct affinity *a)
0025 {
0026 int cpu_set_size = get_cpu_set_size();
0027
0028 a->orig_cpus = bitmap_zalloc(cpu_set_size * 8);
0029 if (!a->orig_cpus)
0030 return -1;
0031 sched_getaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus);
0032 a->sched_cpus = bitmap_zalloc(cpu_set_size * 8);
0033 if (!a->sched_cpus) {
0034 zfree(&a->orig_cpus);
0035 return -1;
0036 }
0037 bitmap_zero((unsigned long *)a->sched_cpus, cpu_set_size);
0038 a->changed = false;
0039 return 0;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048 void affinity__set(struct affinity *a, int cpu)
0049 {
0050 int cpu_set_size = get_cpu_set_size();
0051
0052
0053
0054
0055
0056
0057 if (cpu == -1 || ((cpu >= (cpu_set_size * 8))))
0058 return;
0059
0060 a->changed = true;
0061 set_bit(cpu, a->sched_cpus);
0062
0063
0064
0065
0066
0067 sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->sched_cpus);
0068 clear_bit(cpu, a->sched_cpus);
0069 }
0070
0071 static void __affinity__cleanup(struct affinity *a)
0072 {
0073 int cpu_set_size = get_cpu_set_size();
0074
0075 if (a->changed)
0076 sched_setaffinity(0, cpu_set_size, (cpu_set_t *)a->orig_cpus);
0077 zfree(&a->sched_cpus);
0078 zfree(&a->orig_cpus);
0079 }
0080
0081 void affinity__cleanup(struct affinity *a)
0082 {
0083 if (a != NULL)
0084 __affinity__cleanup(a);
0085 }