--- old/src/os/linux/vm/os_linux.cpp Wed Aug 3 14:50:05 2011 +++ new/src/os/linux/vm/os_linux.cpp Wed Aug 3 14:50:05 2011 @@ -125,6 +125,10 @@ # include # include +#ifdef AMD64 +#include +#endif + #define MAX_PATH (2 * K) // for timer info max values which include all bits @@ -2578,6 +2582,22 @@ return end; } + +int os::Linux::sched_getcpu_syscall(void) { + unsigned int cpu; + int retval = -1; + +#if defined(IA32) + retval = syscall(SYS_getcpu, &cpu, NULL, NULL); +#elif defined(AMD64) + typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache); + vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu); + retval = vgetcpu(&cpu, NULL, NULL); +#endif + + return (retval == -1) ? retval : cpu; +} + // Something to do with the numa-aware allocator needs these symbols extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } extern "C" JNIEXPORT void numa_error(char *where) { } @@ -2601,6 +2621,10 @@ set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, dlsym(RTLD_DEFAULT, "sched_getcpu"))); + // If it's not, try a direct syscall. + if (sched_getcpu() == -1) + set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall)); + if (sched_getcpu() != -1) { // Does it work? void *handle = dlopen("libnuma.so.1", RTLD_LAZY); if (handle != NULL) { --- old/src/os/linux/vm/os_linux.hpp Wed Aug 3 14:50:07 2011 +++ new/src/os/linux/vm/os_linux.hpp Wed Aug 3 14:50:07 2011 @@ -263,6 +263,7 @@ static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } + static int sched_getcpu_syscall(void); public: static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {