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) |