CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CPUAffinity.cc
Go to the documentation of this file.
2 
3 #include <cstdlib>
4 
5 #ifdef __linux
6 
7 #include <sched.h>
8 
9 #if ! __GLIBC_PREREQ(2, 6)
10 // CPU_COUNT is not defined in glibc 2.5, use a gcc builtin instead
11 
12 static
13 size_t cpu_count(cpu_set_t const * cpu_set)
14 {
15  // cpu_set_t is an array of__cpu_mask, a typedef for unsigned long int
16  size_t count = 0;
17  for (unsigned int i = 0; i < sizeof(cpu_set_t) / sizeof(__cpu_mask); ++i)
18  count += __builtin_popcountl(cpu_set->__bits[i]);
19  return count;
20 }
21 #define CPU_COUNT(CPU_SET) cpu_count(CPU_SET)
22 
23 // sched_getcpu is not defined in glibc 2.5, use a syscall to work around it
24 // code adapted from IcedTea
25 
26 #if defined(__x86_64__)
27 #include <asm/vsyscall.h>
28 #elif defined(__i386__)
29 #include <sys/syscall.h>
30 #endif
31 
32 static
33 int sched_getcpu(void)
34 {
35  unsigned int cpu;
36  int retval = -1;
37 #if defined(__x86_64__)
38  typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
39  vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
40  retval = vgetcpu(&cpu, NULL, NULL);
41 #elif defined(__i386__)
42  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
43 #endif
44  return (retval == -1) ? retval : cpu;
45 }
46 
47 #endif // ! __GLIBC_PREREQ(2, 6)
48 #endif // __lixnux
49 
50 
52  // cpu affinity is currently only supposted on LINUX
53 #ifdef __linux
54  return sched_getcpu();
55 #else
56  return 0;
57 #endif
58 }
59 
61 {
62  // cpu affinity is currently only supposted on LINUX
63 #ifdef __linux
64 
65  // check if this process is bound to a single CPU
66  cpu_set_t cpu_set;
67  sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
68  if (CPU_COUNT(& cpu_set) == 1)
69  // the process is bound to a single CPU
70  return true;
71 
72 #endif // __linux
73 
74  return false;
75 }
76 
77 
79 {
80  // cpu affinity is currently only supposted on LINUX
81 #ifdef __linux
82 
83  // check if this process is bound to a single CPU, and try to bind to the current one if it's not
84  cpu_set_t cpu_set;
85  sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
86  if (CPU_COUNT(& cpu_set) == 1)
87  // the process is already bound to a single CPU
88  return true;
89 
90  // this process is not bound, try to bind it to the current CPU
91  int current = sched_getcpu();
92  CPU_ZERO(& cpu_set);
93  CPU_SET(current, & cpu_set);
94  sched_setaffinity(0, sizeof(cpu_set_t), & cpu_set); // check for errors ?
95  sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
96 
97  if (CPU_COUNT(& cpu_set) == 1)
98  // the process is now bound to a single CPU
99  return true;
100 
101 #endif // __linux
102 
103  return false;
104 }
int i
Definition: DBlmapReader.cc:9
#define NULL
Definition: scimark2.h:8
static bool isCpuBound()
Definition: CPUAffinity.cc:60
static int currentCpu()
Definition: CPUAffinity.cc:51
static bool bindToCurrentCpu()
Definition: CPUAffinity.cc:78