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.