Mercurial > hg > graal-jvmci-8
comparison src/os/linux/vm/os_linux.cpp @ 141:fcbfc50865ab
6684395: Port NUMA-aware allocator to linux
Summary: NUMA-aware allocator port to Linux
Reviewed-by: jmasa, apetrusenko
author | iveresov |
---|---|
date | Tue, 29 Apr 2008 13:51:26 +0400 |
parents | 82db0859acbe |
children | d1605aabd0a1 f139919897d2 37f87013dfd8 |
comparison
equal
deleted
inserted
replaced
140:3febac328d82 | 141:fcbfc50865ab |
---|---|
2226 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) { | 2226 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint) { |
2227 return commit_memory(addr, size); | 2227 return commit_memory(addr, size); |
2228 } | 2228 } |
2229 | 2229 |
2230 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } | 2230 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } |
2231 void os::free_memory(char *addr, size_t bytes) { } | 2231 |
2232 void os::free_memory(char *addr, size_t bytes) { | |
2233 uncommit_memory(addr, bytes); | |
2234 } | |
2235 | |
2232 void os::numa_make_global(char *addr, size_t bytes) { } | 2236 void os::numa_make_global(char *addr, size_t bytes) { } |
2233 void os::numa_make_local(char *addr, size_t bytes) { } | 2237 |
2234 bool os::numa_topology_changed() { return false; } | 2238 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { |
2235 size_t os::numa_get_groups_num() { return 1; } | 2239 Linux::numa_tonode_memory(addr, bytes, lgrp_hint); |
2236 int os::numa_get_group_id() { return 0; } | 2240 } |
2241 | |
2242 bool os::numa_topology_changed() { return false; } | |
2243 | |
2244 size_t os::numa_get_groups_num() { | |
2245 int max_node = Linux::numa_max_node(); | |
2246 return max_node > 0 ? max_node + 1 : 1; | |
2247 } | |
2248 | |
2249 int os::numa_get_group_id() { | |
2250 int cpu_id = Linux::sched_getcpu(); | |
2251 if (cpu_id != -1) { | |
2252 int lgrp_id = Linux::get_node_by_cpu(cpu_id); | |
2253 if (lgrp_id != -1) { | |
2254 return lgrp_id; | |
2255 } | |
2256 } | |
2257 return 0; | |
2258 } | |
2259 | |
2237 size_t os::numa_get_leaf_groups(int *ids, size_t size) { | 2260 size_t os::numa_get_leaf_groups(int *ids, size_t size) { |
2238 if (size > 0) { | 2261 for (size_t i = 0; i < size; i++) { |
2239 ids[0] = 0; | 2262 ids[i] = i; |
2240 return 1; | 2263 } |
2241 } | 2264 return size; |
2242 return 0; | |
2243 } | 2265 } |
2244 | 2266 |
2245 bool os::get_page_info(char *start, page_info* info) { | 2267 bool os::get_page_info(char *start, page_info* info) { |
2246 return false; | 2268 return false; |
2247 } | 2269 } |
2248 | 2270 |
2249 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | 2271 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { |
2250 return end; | 2272 return end; |
2251 } | 2273 } |
2274 | |
2275 extern "C" void numa_warn(int number, char *where, ...) { } | |
2276 extern "C" void numa_error(char *where) { } | |
2277 | |
2278 void os::Linux::libnuma_init() { | |
2279 // sched_getcpu() should be in libc. | |
2280 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, | |
2281 dlsym(RTLD_DEFAULT, "sched_getcpu"))); | |
2282 | |
2283 if (sched_getcpu() != -1) { // Does it work? | |
2284 void *handle = dlopen("libnuma.so", RTLD_LAZY); | |
2285 if (handle != NULL) { | |
2286 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, | |
2287 dlsym(handle, "numa_node_to_cpus"))); | |
2288 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t, | |
2289 dlsym(handle, "numa_max_node"))); | |
2290 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t, | |
2291 dlsym(handle, "numa_available"))); | |
2292 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t, | |
2293 dlsym(handle, "numa_tonode_memory"))); | |
2294 if (numa_available() != -1) { | |
2295 // Create a cpu -> node mapping | |
2296 _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true); | |
2297 rebuild_cpu_to_node_map(); | |
2298 } | |
2299 } | |
2300 } | |
2301 } | |
2302 | |
2303 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id. | |
2304 // The table is later used in get_node_by_cpu(). | |
2305 void os::Linux::rebuild_cpu_to_node_map() { | |
2306 int cpu_num = os::active_processor_count(); | |
2307 cpu_to_node()->clear(); | |
2308 cpu_to_node()->at_grow(cpu_num - 1); | |
2309 int node_num = numa_get_groups_num(); | |
2310 int cpu_map_size = (cpu_num + BitsPerLong - 1) / BitsPerLong; | |
2311 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size); | |
2312 for (int i = 0; i < node_num; i++) { | |
2313 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { | |
2314 for (int j = 0; j < cpu_map_size; j++) { | |
2315 if (cpu_map[j] != 0) { | |
2316 for (int k = 0; k < BitsPerLong; k++) { | |
2317 if (cpu_map[j] & (1UL << k)) { | |
2318 cpu_to_node()->at_put(j * BitsPerLong + k, i); | |
2319 } | |
2320 } | |
2321 } | |
2322 } | |
2323 } | |
2324 } | |
2325 FREE_C_HEAP_ARRAY(unsigned long, cpu_map); | |
2326 } | |
2327 | |
2328 int os::Linux::get_node_by_cpu(int cpu_id) { | |
2329 if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) { | |
2330 return cpu_to_node()->at(cpu_id); | |
2331 } | |
2332 return -1; | |
2333 } | |
2334 | |
2335 GrowableArray<int>* os::Linux::_cpu_to_node; | |
2336 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu; | |
2337 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus; | |
2338 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; | |
2339 os::Linux::numa_available_func_t os::Linux::_numa_available; | |
2340 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; | |
2341 | |
2252 | 2342 |
2253 bool os::uncommit_memory(char* addr, size_t size) { | 2343 bool os::uncommit_memory(char* addr, size_t size) { |
2254 return ::mmap(addr, size, | 2344 return ::mmap(addr, size, |
2255 PROT_READ|PROT_WRITE|PROT_EXEC, | 2345 PROT_READ|PROT_WRITE|PROT_EXEC, |
2256 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) | 2346 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) |
3548 Linux::libpthread_init(); | 3638 Linux::libpthread_init(); |
3549 if (PrintMiscellaneous && (Verbose || WizardMode)) { | 3639 if (PrintMiscellaneous && (Verbose || WizardMode)) { |
3550 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", | 3640 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", |
3551 Linux::glibc_version(), Linux::libpthread_version(), | 3641 Linux::glibc_version(), Linux::libpthread_version(), |
3552 Linux::is_floating_stack() ? "floating stack" : "fixed stack"); | 3642 Linux::is_floating_stack() ? "floating stack" : "fixed stack"); |
3643 } | |
3644 | |
3645 if (UseNUMA) { | |
3646 Linux::libnuma_init(); | |
3553 } | 3647 } |
3554 | 3648 |
3555 if (MaxFDLimit) { | 3649 if (MaxFDLimit) { |
3556 // set the number of file descriptors to max. print out error | 3650 // set the number of file descriptors to max. print out error |
3557 // if getrlimit/setrlimit fails but continue regardless. | 3651 // if getrlimit/setrlimit fails but continue regardless. |