2270 |
2270 |
2271 void os::free_memory(char *addr, size_t bytes) { |
2271 void os::free_memory(char *addr, size_t bytes) { |
2272 uncommit_memory(addr, bytes); |
2272 uncommit_memory(addr, bytes); |
2273 } |
2273 } |
2274 |
2274 |
2275 void os::numa_make_global(char *addr, size_t bytes) { } |
2275 void os::numa_make_global(char *addr, size_t bytes) { |
|
2276 Linux::numa_interleave_memory(addr, bytes); |
|
2277 } |
2276 |
2278 |
2277 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { |
2279 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { |
2278 Linux::numa_tonode_memory(addr, bytes, lgrp_hint); |
2280 Linux::numa_tonode_memory(addr, bytes, lgrp_hint); |
2279 } |
2281 } |
2280 |
2282 |
2312 } |
2314 } |
2313 |
2315 |
2314 extern "C" void numa_warn(int number, char *where, ...) { } |
2316 extern "C" void numa_warn(int number, char *where, ...) { } |
2315 extern "C" void numa_error(char *where) { } |
2317 extern "C" void numa_error(char *where) { } |
2316 |
2318 |
2317 void os::Linux::libnuma_init() { |
2319 bool os::Linux::libnuma_init() { |
2318 // sched_getcpu() should be in libc. |
2320 // sched_getcpu() should be in libc. |
2319 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, |
2321 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, |
2320 dlsym(RTLD_DEFAULT, "sched_getcpu"))); |
2322 dlsym(RTLD_DEFAULT, "sched_getcpu"))); |
2321 |
2323 |
2322 if (sched_getcpu() != -1) { // Does it work? |
2324 if (sched_getcpu() != -1) { // Does it work? |
2328 dlsym(handle, "numa_max_node"))); |
2330 dlsym(handle, "numa_max_node"))); |
2329 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t, |
2331 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t, |
2330 dlsym(handle, "numa_available"))); |
2332 dlsym(handle, "numa_available"))); |
2331 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t, |
2333 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t, |
2332 dlsym(handle, "numa_tonode_memory"))); |
2334 dlsym(handle, "numa_tonode_memory"))); |
|
2335 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, |
|
2336 dlsym(handle, "numa_interleave_memory"))); |
|
2337 |
|
2338 |
2333 if (numa_available() != -1) { |
2339 if (numa_available() != -1) { |
|
2340 set_numa_all_nodes((unsigned long*)dlsym(handle, "numa_all_nodes")); |
2334 // Create a cpu -> node mapping |
2341 // Create a cpu -> node mapping |
2335 _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true); |
2342 _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true); |
2336 rebuild_cpu_to_node_map(); |
2343 rebuild_cpu_to_node_map(); |
|
2344 return true; |
2337 } |
2345 } |
2338 } |
2346 } |
2339 } |
2347 } |
|
2348 return false; |
2340 } |
2349 } |
2341 |
2350 |
2342 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id. |
2351 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id. |
2343 // The table is later used in get_node_by_cpu(). |
2352 // The table is later used in get_node_by_cpu(). |
2344 void os::Linux::rebuild_cpu_to_node_map() { |
2353 void os::Linux::rebuild_cpu_to_node_map() { |
2345 int cpu_num = os::active_processor_count(); |
2354 const size_t NCPUS = 32768; // Since the buffer size computation is very obscure |
|
2355 // in libnuma (possible values are starting from 16, |
|
2356 // and continuing up with every other power of 2, but less |
|
2357 // than the maximum number of CPUs supported by kernel), and |
|
2358 // is a subject to change (in libnuma version 2 the requirements |
|
2359 // are more reasonable) we'll just hardcode the number they use |
|
2360 // in the library. |
|
2361 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT; |
|
2362 |
|
2363 size_t cpu_num = os::active_processor_count(); |
|
2364 size_t cpu_map_size = NCPUS / BitsPerCLong; |
|
2365 size_t cpu_map_valid_size = |
|
2366 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size); |
|
2367 |
2346 cpu_to_node()->clear(); |
2368 cpu_to_node()->clear(); |
2347 cpu_to_node()->at_grow(cpu_num - 1); |
2369 cpu_to_node()->at_grow(cpu_num - 1); |
2348 int node_num = numa_get_groups_num(); |
2370 size_t node_num = numa_get_groups_num(); |
2349 int cpu_map_size = (cpu_num + BitsPerLong - 1) / BitsPerLong; |
2371 |
2350 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size); |
2372 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size); |
2351 for (int i = 0; i < node_num; i++) { |
2373 for (size_t i = 0; i < node_num; i++) { |
2352 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { |
2374 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { |
2353 for (int j = 0; j < cpu_map_size; j++) { |
2375 for (size_t j = 0; j < cpu_map_valid_size; j++) { |
2354 if (cpu_map[j] != 0) { |
2376 if (cpu_map[j] != 0) { |
2355 for (int k = 0; k < BitsPerLong; k++) { |
2377 for (size_t k = 0; k < BitsPerCLong; k++) { |
2356 if (cpu_map[j] & (1UL << k)) { |
2378 if (cpu_map[j] & (1UL << k)) { |
2357 cpu_to_node()->at_put(j * BitsPerLong + k, i); |
2379 cpu_to_node()->at_put(j * BitsPerCLong + k, i); |
2358 } |
2380 } |
2359 } |
2381 } |
2360 } |
2382 } |
2361 } |
2383 } |
2362 } |
2384 } |
2375 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu; |
2397 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu; |
2376 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus; |
2398 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus; |
2377 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; |
2399 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; |
2378 os::Linux::numa_available_func_t os::Linux::_numa_available; |
2400 os::Linux::numa_available_func_t os::Linux::_numa_available; |
2379 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; |
2401 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; |
2380 |
2402 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; |
|
2403 unsigned long* os::Linux::_numa_all_nodes; |
2381 |
2404 |
2382 bool os::uncommit_memory(char* addr, size_t size) { |
2405 bool os::uncommit_memory(char* addr, size_t size) { |
2383 return ::mmap(addr, size, |
2406 return ::mmap(addr, size, |
2384 PROT_READ|PROT_WRITE|PROT_EXEC, |
2407 PROT_READ|PROT_WRITE|PROT_EXEC, |
2385 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) |
2408 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0) |