CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/HLTrigger/Timer/src/CPUAffinity.cc

Go to the documentation of this file.
00001 #include "HLTrigger/Timer/interface/CPUAffinity.h"
00002 
00003 #include <cstdlib>
00004 
00005 #ifdef __linux
00006 
00007 #include <sched.h>
00008 
00009 #if ! __GLIBC_PREREQ(2, 6)
00010 // CPU_COUNT is not defined in glibc 2.5, use a gcc builtin instead
00011 
00012 static
00013 size_t cpu_count(cpu_set_t const * cpu_set) 
00014 {
00015   // cpu_set_t is an array of__cpu_mask, a typedef for unsigned long int
00016   size_t count = 0;
00017   for (unsigned int i = 0; i < sizeof(cpu_set_t) / sizeof(__cpu_mask); ++i)
00018     count += __builtin_popcountl(cpu_set->__bits[i]);
00019   return count;
00020 }
00021 #define CPU_COUNT(CPU_SET) cpu_count(CPU_SET)
00022 
00023 // sched_getcpu is not defined in glibc 2.5, use a syscall to work around it
00024 // code adapted from IcedTea
00025 
00026 #if defined(__x86_64__)
00027 #include <asm/vsyscall.h>
00028 #elif defined(__i386__)                                                                                                                                                                                                          
00029 #include <sys/syscall.h>
00030 #endif
00031 
00032 static 
00033 int sched_getcpu(void) 
00034 {
00035   unsigned int cpu;
00036   int retval = -1;
00037 #if defined(__x86_64__)
00038   typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
00039   vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
00040   retval = vgetcpu(&cpu, NULL, NULL);
00041 #elif defined(__i386__)
00042   retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
00043 #endif
00044   return (retval == -1) ? retval : cpu;
00045 }
00046 
00047 #endif // ! __GLIBC_PREREQ(2, 6)
00048 #endif // __lixnux
00049 
00050 
00051 int CPUAffinity::currentCpu() {
00052   // cpu affinity is currently only supposted on LINUX
00053 #ifdef __linux
00054   return sched_getcpu();
00055 #else
00056   return 0;
00057 #endif
00058 }
00059 
00060 bool CPUAffinity::isCpuBound()
00061 {
00062   // cpu affinity is currently only supposted on LINUX
00063 #ifdef __linux
00064 
00065   // check if this process is bound to a single CPU
00066   cpu_set_t cpu_set;
00067   sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
00068   if (CPU_COUNT(& cpu_set) == 1)
00069     // the process is bound to a single CPU
00070     return true;
00071 
00072 #endif // __linux
00073 
00074   return false;
00075 }
00076 
00077 
00078 bool CPUAffinity::bindToCurrentCpu()
00079 {
00080   // cpu affinity is currently only supposted on LINUX
00081 #ifdef __linux
00082 
00083   // check if this process is bound to a single CPU, and try to bind to the current one if it's not
00084   cpu_set_t cpu_set;
00085   sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
00086   if (CPU_COUNT(& cpu_set) == 1)
00087     // the process is already bound to a single CPU
00088     return true;
00089   
00090   // this process is not bound, try to bind it to the current CPU
00091   int current = sched_getcpu();
00092   CPU_ZERO(& cpu_set);
00093   CPU_SET(current, & cpu_set);
00094   sched_setaffinity(0, sizeof(cpu_set_t), & cpu_set); // check for errors ?
00095   sched_getaffinity(0, sizeof(cpu_set_t), & cpu_set);
00096 
00097   if (CPU_COUNT(& cpu_set) == 1)
00098     // the process is now bound to a single CPU
00099     return true;
00100 
00101 #endif // __linux
00102 
00103   return false;
00104 }