There is an error in syst.c which manifests itself on big-endian machines when
syst.c is compiled in 32-bit mode.
The bit vector which is used to describe the cpus that you want to set the
affinity for is an array of 32-bit words (when using the
compat_sys_sched_setaffinity system call in 32-bit mode). syst programs a
vector of 64-bit words. On a little endian machine, this wouldn't matter,
because the least significant byte of the 32-bit or 64-bit word is always at
offset 0. But on a big-endian machine, the least significant byte is at offset
0x3 or 0x7 depending on the word size. So the result is that the bit vector is
interpreted as setting the affinity for a cpu which does not exist.
There are a couple of ways to fix this, and this patch contains both variants,
depending on whether the OS_HAS_SCHED_SETAFFINITY_LIB_CALL macro is either
defined or not.
I assume that when syst.c was originally written, a library call for
sched_setaffinity wasn't available, and may still not be available on some older
OS's. So you can choose how you want to fix this problem, either by using the
library call, or by using the other variant I included which does not use the
library call, but instead uses code that's more flexible to the size of the
words in the cpu set vector. You can decide which one you want to commit (if
either), and then cut out the variant you didn't use.
Signed-off-by: Corey Ashford <cjash...@us.ibm.com>
Thanks for your consideration,
- Corey
Corey Ashford
Software Engineer
IBM Linux Technology Center, Linux Toolchain
Beaverton, OR
503-578-3507
cjash...@us.ibm.com
Index: examples_v2.x/syst.c
===================================================================
RCS file: /cvsroot/perfmon2/libpfm/examples_v2.x/syst.c,v
retrieving revision 1.2
diff -u -p -r1.2 syst.c
--- examples_v2.x/syst.c 7 Nov 2008 13:52:54 -0000 1.2
+++ examples_v2.x/syst.c 25 Aug 2009 23:48:44 -0000
@@ -30,6 +30,10 @@
#include <unistd.h>
#include <string.h>
#include <syscall.h>
+#if OS_HAS_SCHED_SETAFFINITY_LIB_CALL
+#include <sched.h>
+#endif
+
#include <perfmon/pfmlib.h>
#include <perfmon/perfmon.h>
@@ -56,27 +60,49 @@ fatal_error(char *fmt, ...)
exit(1);
}
+
/*
* pin task to CPU
*/
+
+#define MAX_CPUS 2048
+
+#if OS_HAS_SCHED_SETAFFINITY_LIB_CALL
+int
+pin_cpu(pid_t pid, unsigned int cpu)
+{
+ cpu_set_t my_set;
+ CPU_ZERO(&my_set);
+
+ if (cpu >= MAX_CPUS)
+ fatal_error("this program supports only up to %d CPUs\n",
MAX_CPUS);
+
+ CPU_SET(cpu, &my_set);
+
+ return sched_setaffinity(pid, sizeof(cpu_set_t), &my_set);
+}
+#else
+
+#define NR_BITS_PER_VEC (sizeof(unsigned long) * 8)
+#define NR_CPU_BITS (MAX_CPUS / sizeof(unsigned long))
+
#ifndef __NR_sched_setaffinity
#error "you need to define __NR_sched_setaffinity"
#endif
-#define MAX_CPUS 2048
-#define NR_CPU_BITS (MAX_CPUS>>3)
int
pin_cpu(pid_t pid, unsigned int cpu)
{
- uint64_t my_mask[NR_CPU_BITS];
+ unsigned long my_mask[NR_CPU_BITS];
if (cpu >= MAX_CPUS)
fatal_error("this program supports only up to %d CPUs\n",
MAX_CPUS);
- my_mask[cpu>>6] = 1ULL << (cpu&63);
+ my_mask[cpu / NR_BITS_PER_VEC] = 1ULL << (cpu % NR_BITS_PER_VEC);
return syscall(__NR_sched_setaffinity, pid, sizeof(my_mask), &my_mask);
}
+#endif
int
main(int argc, char **argv)
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
perfmon2-devel mailing list
perfmon2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perfmon2-devel