hotspot/src/os/linux/vm/os_linux.cpp
changeset 1615 b46d9f19bde2
parent 1388 3677f5f3d66b
child 1664 fc9ed50498fb
equal deleted inserted replaced
1610:5dddd195cc86 1615:b46d9f19bde2
  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)
  3693           Linux::glibc_version(), Linux::libpthread_version(),
  3716           Linux::glibc_version(), Linux::libpthread_version(),
  3694           Linux::is_floating_stack() ? "floating stack" : "fixed stack");
  3717           Linux::is_floating_stack() ? "floating stack" : "fixed stack");
  3695   }
  3718   }
  3696 
  3719 
  3697   if (UseNUMA) {
  3720   if (UseNUMA) {
  3698     Linux::libnuma_init();
  3721     if (!Linux::libnuma_init()) {
       
  3722       UseNUMA = false;
       
  3723     } else {
       
  3724       if ((Linux::numa_max_node() < 1)) {
       
  3725         // There's only one node(they start from 0), disable NUMA.
       
  3726         UseNUMA = false;
       
  3727       }
       
  3728     }
       
  3729     if (!UseNUMA && ForceNUMA) {
       
  3730       UseNUMA = true;
       
  3731     }
  3699   }
  3732   }
  3700 
  3733 
  3701   if (MaxFDLimit) {
  3734   if (MaxFDLimit) {
  3702     // set the number of file descriptors to max. print out error
  3735     // set the number of file descriptors to max. print out error
  3703     // if getrlimit/setrlimit fails but continue regardless.
  3736     // if getrlimit/setrlimit fails but continue regardless.