1 /* |
1 /* |
2 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 1999-2008 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
91 /* Signal number used to suspend/resume a thread */ |
91 /* Signal number used to suspend/resume a thread */ |
92 |
92 |
93 /* do not use any signal number less than SIGSEGV, see 4355769 */ |
93 /* do not use any signal number less than SIGSEGV, see 4355769 */ |
94 static int SR_signum = SIGUSR2; |
94 static int SR_signum = SIGUSR2; |
95 sigset_t SR_sigset; |
95 sigset_t SR_sigset; |
|
96 |
|
97 /* Used to protect dlsym() calls */ |
|
98 static pthread_mutex_t dl_mutex; |
96 |
99 |
97 //////////////////////////////////////////////////////////////////////////////// |
100 //////////////////////////////////////////////////////////////////////////////// |
98 // utility functions |
101 // utility functions |
99 |
102 |
100 static int SR_initialize(); |
103 static int SR_initialize(); |
1502 |
1505 |
1503 const char* os::dll_file_extension() { return ".so"; } |
1506 const char* os::dll_file_extension() { return ".so"; } |
1504 |
1507 |
1505 const char* os::get_temp_directory() { return "/tmp/"; } |
1508 const char* os::get_temp_directory() { return "/tmp/"; } |
1506 |
1509 |
|
1510 void os::dll_build_name( |
|
1511 char* buffer, size_t buflen, const char* pname, const char* fname) { |
|
1512 // copied from libhpi |
|
1513 const size_t pnamelen = pname ? strlen(pname) : 0; |
|
1514 |
|
1515 /* Quietly truncate on buffer overflow. Should be an error. */ |
|
1516 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { |
|
1517 *buffer = '\0'; |
|
1518 return; |
|
1519 } |
|
1520 |
|
1521 if (pnamelen == 0) { |
|
1522 sprintf(buffer, "lib%s.so", fname); |
|
1523 } else { |
|
1524 sprintf(buffer, "%s/lib%s.so", pname, fname); |
|
1525 } |
|
1526 } |
|
1527 |
1507 const char* os::get_current_directory(char *buf, int buflen) { |
1528 const char* os::get_current_directory(char *buf, int buflen) { |
1508 return getcwd(buf, buflen); |
1529 return getcwd(buf, buflen); |
1509 } |
1530 } |
1510 |
1531 |
1511 // check if addr is inside libjvm[_g].so |
1532 // check if addr is inside libjvm[_g].so |
1751 } |
1772 } |
1752 |
1773 |
1753 return NULL; |
1774 return NULL; |
1754 } |
1775 } |
1755 |
1776 |
1756 |
1777 /* |
|
1778 * glibc-2.0 libdl is not MT safe. If you are building with any glibc, |
|
1779 * chances are you might want to run the generated bits against glibc-2.0 |
|
1780 * libdl.so, so always use locking for any version of glibc. |
|
1781 */ |
|
1782 void* os::dll_lookup(void* handle, const char* name) { |
|
1783 pthread_mutex_lock(&dl_mutex); |
|
1784 void* res = dlsym(handle, name); |
|
1785 pthread_mutex_unlock(&dl_mutex); |
|
1786 return res; |
|
1787 } |
1757 |
1788 |
1758 |
1789 |
1759 bool _print_ascii_file(const char* filename, outputStream* st) { |
1790 bool _print_ascii_file(const char* filename, outputStream* st) { |
1760 int fd = open(filename, O_RDONLY); |
1791 int fd = open(filename, O_RDONLY); |
1761 if (fd == -1) { |
1792 if (fd == -1) { |
2287 // sched_getcpu() should be in libc. |
2318 // sched_getcpu() should be in libc. |
2288 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, |
2319 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, |
2289 dlsym(RTLD_DEFAULT, "sched_getcpu"))); |
2320 dlsym(RTLD_DEFAULT, "sched_getcpu"))); |
2290 |
2321 |
2291 if (sched_getcpu() != -1) { // Does it work? |
2322 if (sched_getcpu() != -1) { // Does it work? |
2292 void *handle = dlopen("libnuma.so", RTLD_LAZY); |
2323 void *handle = dlopen("libnuma.so.1", RTLD_LAZY); |
2293 if (handle != NULL) { |
2324 if (handle != NULL) { |
2294 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, |
2325 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, |
2295 dlsym(handle, "numa_node_to_cpus"))); |
2326 dlsym(handle, "numa_node_to_cpus"))); |
2296 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t, |
2327 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t, |
2297 dlsym(handle, "numa_max_node"))); |
2328 dlsym(handle, "numa_max_node"))); |
2423 |
2454 |
2424 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size()); |
2455 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size()); |
2425 return ::mprotect(bottom, size, prot) == 0; |
2456 return ::mprotect(bottom, size, prot) == 0; |
2426 } |
2457 } |
2427 |
2458 |
2428 bool os::protect_memory(char* addr, size_t size) { |
2459 // Set protections specified |
2429 return linux_mprotect(addr, size, PROT_READ); |
2460 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, |
|
2461 bool is_committed) { |
|
2462 unsigned int p = 0; |
|
2463 switch (prot) { |
|
2464 case MEM_PROT_NONE: p = PROT_NONE; break; |
|
2465 case MEM_PROT_READ: p = PROT_READ; break; |
|
2466 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; |
|
2467 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; |
|
2468 default: |
|
2469 ShouldNotReachHere(); |
|
2470 } |
|
2471 // is_committed is unused. |
|
2472 return linux_mprotect(addr, bytes, p); |
2430 } |
2473 } |
2431 |
2474 |
2432 bool os::guard_memory(char* addr, size_t size) { |
2475 bool os::guard_memory(char* addr, size_t size) { |
2433 return linux_mprotect(addr, size, PROT_NONE); |
2476 return linux_mprotect(addr, size, PROT_NONE); |
2434 } |
2477 } |
3578 // main_thread points to the aboriginal thread |
3621 // main_thread points to the aboriginal thread |
3579 Linux::_main_thread = pthread_self(); |
3622 Linux::_main_thread = pthread_self(); |
3580 |
3623 |
3581 Linux::clock_init(); |
3624 Linux::clock_init(); |
3582 initial_time_count = os::elapsed_counter(); |
3625 initial_time_count = os::elapsed_counter(); |
|
3626 pthread_mutex_init(&dl_mutex, NULL); |
3583 } |
3627 } |
3584 |
3628 |
3585 // To install functions for atexit system call |
3629 // To install functions for atexit system call |
3586 extern "C" { |
3630 extern "C" { |
3587 static void perfMemory_exit_helper() { |
3631 static void perfMemory_exit_helper() { |
3713 fatal("Could not disable polling page"); |
3757 fatal("Could not disable polling page"); |
3714 }; |
3758 }; |
3715 |
3759 |
3716 // Mark the polling page as readable |
3760 // Mark the polling page as readable |
3717 void os::make_polling_page_readable(void) { |
3761 void os::make_polling_page_readable(void) { |
3718 if( !protect_memory((char *)_polling_page, Linux::page_size()) ) |
3762 if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) { |
3719 fatal("Could not enable polling page"); |
3763 fatal("Could not enable polling page"); |
|
3764 } |
3720 }; |
3765 }; |
3721 |
3766 |
3722 int os::active_processor_count() { |
3767 int os::active_processor_count() { |
3723 // Linux doesn't yet have a (official) notion of processor sets, |
3768 // Linux doesn't yet have a (official) notion of processor sets, |
3724 // so just return the number of online processors. |
3769 // so just return the number of online processors. |