# HG changeset patch # User iveresov # Date 1312588214 25200 # Node ID 7c2653aefc46a1a3b6683055a72f86313b28c923 # Parent a20e6e447d3dff7d0c554bb778eae5227b1dd9ee 7060836: RHEL 5.5 and 5.6 should support UseNUMA Summary: Add a wrapper for sched_getcpu() for systems where libc lacks it Reviewed-by: ysr Contributed-by: Andrew John Hughes diff -r a20e6e447d3d -r 7c2653aefc46 src/os/linux/vm/os_linux.cpp --- a/src/os/linux/vm/os_linux.cpp Fri Aug 05 16:44:01 2011 -0700 +++ b/src/os/linux/vm/os_linux.cpp Fri Aug 05 16:50:14 2011 -0700 @@ -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) { diff -r a20e6e447d3d -r 7c2653aefc46 src/os/linux/vm/os_linux.hpp --- a/src/os/linux/vm/os_linux.hpp Fri Aug 05 16:44:01 2011 -0700 +++ b/src/os/linux/vm/os_linux.hpp Fri Aug 05 16:50:14 2011 -0700 @@ -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) {