changeset 25064 | 244218e6ec0a |
parent 24351 | 61b33cc6d3cf |
child 25333 | 078d0ef28601 |
child 25351 | 7c198a690050 |
25063:fc4e54527641 | 25064:244218e6ec0a |
---|---|
210 sp >= thread->_stack_base - thread->_stack_size) || |
210 sp >= thread->_stack_base - thread->_stack_size) || |
211 is_error_reported(), |
211 is_error_reported(), |
212 "sp must be inside of selected thread stack"); |
212 "sp must be inside of selected thread stack"); |
213 |
213 |
214 thread->set_self_raw_id(raw_id); // mark for quick retrieval |
214 thread->set_self_raw_id(raw_id); // mark for quick retrieval |
215 _get_thread_cache[ index ] = thread; |
215 _get_thread_cache[index] = thread; |
216 } |
216 } |
217 return thread; |
217 return thread; |
218 } |
218 } |
219 |
219 |
220 |
220 |
221 static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0}; |
221 static const double all_zero[sizeof(Thread) / sizeof(double) + 1] = {0}; |
222 #define NO_CACHED_THREAD ((Thread*)all_zero) |
222 #define NO_CACHED_THREAD ((Thread*)all_zero) |
223 |
223 |
224 void ThreadLocalStorage::pd_set_thread(Thread* thread) { |
224 void ThreadLocalStorage::pd_set_thread(Thread* thread) { |
225 |
225 |
226 // Store the new value before updating the cache to prevent a race |
226 // Store the new value before updating the cache to prevent a race |
268 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); |
268 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); |
269 return st; |
269 return st; |
270 } |
270 } |
271 |
271 |
272 address os::current_stack_base() { |
272 address os::current_stack_base() { |
273 int r = thr_main() ; |
273 int r = thr_main(); |
274 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; |
274 guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); |
275 bool is_primordial_thread = r; |
275 bool is_primordial_thread = r; |
276 |
276 |
277 // Workaround 4352906, avoid calls to thr_stksegment by |
277 // Workaround 4352906, avoid calls to thr_stksegment by |
278 // thr_main after the first one (it looks like we trash |
278 // thr_main after the first one (it looks like we trash |
279 // some data, causing the value for ss_sp to be incorrect). |
279 // some data, causing the value for ss_sp to be incorrect). |
291 } |
291 } |
292 |
292 |
293 size_t os::current_stack_size() { |
293 size_t os::current_stack_size() { |
294 size_t size; |
294 size_t size; |
295 |
295 |
296 int r = thr_main() ; |
296 int r = thr_main(); |
297 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; |
297 guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); |
298 if(!r) { |
298 if (!r) { |
299 size = get_stack_info().ss_size; |
299 size = get_stack_info().ss_size; |
300 } else { |
300 } else { |
301 struct rlimit limits; |
301 struct rlimit limits; |
302 getrlimit(RLIMIT_STACK, &limits); |
302 getrlimit(RLIMIT_STACK, &limits); |
303 size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur); |
303 size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur); |
407 // In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's |
407 // In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's |
408 // not available on S8.0. |
408 // not available on S8.0. |
409 |
409 |
410 static bool find_processors_online(processorid_t** id_array, |
410 static bool find_processors_online(processorid_t** id_array, |
411 uint* id_length) { |
411 uint* id_length) { |
412 const processorid_t MAX_PROCESSOR_ID = 100000 ; |
412 const processorid_t MAX_PROCESSOR_ID = 100000; |
413 // Find the number of processors online. |
413 // Find the number of processors online. |
414 *id_length = sysconf(_SC_NPROCESSORS_ONLN); |
414 *id_length = sysconf(_SC_NPROCESSORS_ONLN); |
415 // Make up an array to hold their ids. |
415 // Make up an array to hold their ids. |
416 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); |
416 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); |
417 // Processors need not be numbered consecutively. |
417 // Processors need not be numbered consecutively. |
434 // and re-running the loop, above, but there's no guarantee of progress |
434 // and re-running the loop, above, but there's no guarantee of progress |
435 // if the system configuration is in flux. Instead, we just return what |
435 // if the system configuration is in flux. Instead, we just return what |
436 // we've got. Note that in the worst case find_processors_online() could |
436 // we've got. Note that in the worst case find_processors_online() could |
437 // return an empty set. (As a fall-back in the case of the empty set we |
437 // return an empty set. (As a fall-back in the case of the empty set we |
438 // could just return the ID of the current processor). |
438 // could just return the ID of the current processor). |
439 *id_length = found ; |
439 *id_length = found; |
440 } |
440 } |
441 |
441 |
442 return true; |
442 return true; |
443 } |
443 } |
444 |
444 |
550 NULL); // don't return old binding. |
550 NULL); // don't return old binding. |
551 return (bind_result == 0); |
551 return (bind_result == 0); |
552 } |
552 } |
553 |
553 |
554 bool os::getenv(const char* name, char* buffer, int len) { |
554 bool os::getenv(const char* name, char* buffer, int len) { |
555 char* val = ::getenv( name ); |
555 char* val = ::getenv(name); |
556 if ( val == NULL |
556 if (val == NULL |
557 || strlen(val) + 1 > len ) { |
557 || strlen(val) + 1 > len ) { |
558 if (len > 0) buffer[0] = 0; // return a null string |
558 if (len > 0) buffer[0] = 0; // return a null string |
559 return false; |
559 return false; |
560 } |
560 } |
561 strcpy( buffer, val ); |
561 strcpy(buffer, val); |
562 return true; |
562 return true; |
563 } |
563 } |
564 |
564 |
565 |
565 |
566 // Return true if user is running as root. |
566 // Return true if user is running as root. |
670 char *library_path; |
670 char *library_path; |
671 char *common_path = buf; |
671 char *common_path = buf; |
672 |
672 |
673 // Determine search path count and required buffer size. |
673 // Determine search path count and required buffer size. |
674 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) { |
674 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) { |
675 FREE_C_HEAP_ARRAY(char, buf, mtInternal); |
675 FREE_C_HEAP_ARRAY(char, buf, mtInternal); |
676 vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror()); |
676 vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror()); |
677 } |
677 } |
678 |
678 |
679 // Allocate new buffer and initialize. |
679 // Allocate new buffer and initialize. |
680 info = (Dl_serinfo*)NEW_C_HEAP_ARRAY(char, info_sz.dls_size, mtInternal); |
680 info = (Dl_serinfo*)NEW_C_HEAP_ARRAY(char, info_sz.dls_size, mtInternal); |
681 info->dls_size = info_sz.dls_size; |
681 info->dls_size = info_sz.dls_size; |
682 info->dls_cnt = info_sz.dls_cnt; |
682 info->dls_cnt = info_sz.dls_cnt; |
683 |
683 |
684 // Obtain search path information. |
684 // Obtain search path information. |
685 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) { |
685 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) { |
686 FREE_C_HEAP_ARRAY(char, buf, mtInternal); |
686 FREE_C_HEAP_ARRAY(char, buf, mtInternal); |
687 FREE_C_HEAP_ARRAY(char, info, mtInternal); |
687 FREE_C_HEAP_ARRAY(char, info, mtInternal); |
688 vm_exit_during_initialization("dlinfo SERINFO request", dlerror()); |
688 vm_exit_during_initialization("dlinfo SERINFO request", dlerror()); |
689 } |
689 } |
690 |
690 |
691 path = &info->dls_serpath[0]; |
691 path = &info->dls_serpath[0]; |
792 } |
792 } |
793 |
793 |
794 bool os::Solaris::valid_stack_address(Thread* thread, address sp) { |
794 bool os::Solaris::valid_stack_address(Thread* thread, address sp) { |
795 address stackStart = (address)thread->stack_base(); |
795 address stackStart = (address)thread->stack_base(); |
796 address stackEnd = (address)(stackStart - (address)thread->stack_size()); |
796 address stackEnd = (address)(stackStart - (address)thread->stack_size()); |
797 if (sp < stackStart && sp >= stackEnd ) return true; |
797 if (sp < stackStart && sp >= stackEnd) return true; |
798 return false; |
798 return false; |
799 } |
799 } |
800 |
800 |
801 extern "C" void breakpoint() { |
801 extern "C" void breakpoint() { |
802 // use debugger to set breakpoint here |
802 // use debugger to set breakpoint here |
817 |
817 |
818 int prio; |
818 int prio; |
819 Thread* thread = (Thread*)thread_addr; |
819 Thread* thread = (Thread*)thread_addr; |
820 OSThread* osthr = thread->osthread(); |
820 OSThread* osthr = thread->osthread(); |
821 |
821 |
822 osthr->set_lwp_id( _lwp_self() ); // Store lwp in case we are bound |
822 osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound |
823 thread->_schedctl = (void *) schedctl_init () ; |
823 thread->_schedctl = (void *) schedctl_init(); |
824 |
824 |
825 if (UseNUMA) { |
825 if (UseNUMA) { |
826 int lgrp_id = os::numa_get_group_id(); |
826 int lgrp_id = os::numa_get_group_id(); |
827 if (lgrp_id != -1) { |
827 if (lgrp_id != -1) { |
828 thread->set_lgrp_id(lgrp_id); |
828 thread->set_lgrp_id(lgrp_id); |
837 // in java_to_os_priority, so when we read it back here, |
837 // in java_to_os_priority, so when we read it back here, |
838 // we pass trash to set_native_priority instead of what's |
838 // we pass trash to set_native_priority instead of what's |
839 // in java_to_os_priority. So we save the native priority |
839 // in java_to_os_priority. So we save the native priority |
840 // in the osThread and recall it here. |
840 // in the osThread and recall it here. |
841 |
841 |
842 if ( osthr->thread_id() != -1 ) { |
842 if (osthr->thread_id() != -1) { |
843 if ( UseThreadPriorities ) { |
843 if (UseThreadPriorities) { |
844 int prio = osthr->native_priority(); |
844 int prio = osthr->native_priority(); |
845 if (ThreadPriorityVerbose) { |
845 if (ThreadPriorityVerbose) { |
846 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " |
846 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " |
847 INTPTR_FORMAT ", setting priority: %d\n", |
847 INTPTR_FORMAT ", setting priority: %d\n", |
848 osthr->thread_id(), osthr->lwp_id(), prio); |
848 osthr->thread_id(), osthr->lwp_id(), prio); |
880 if (osthread == NULL) return NULL; |
880 if (osthread == NULL) return NULL; |
881 |
881 |
882 // Store info on the Solaris thread into the OSThread |
882 // Store info on the Solaris thread into the OSThread |
883 osthread->set_thread_id(thread_id); |
883 osthread->set_thread_id(thread_id); |
884 osthread->set_lwp_id(_lwp_self()); |
884 osthread->set_lwp_id(_lwp_self()); |
885 thread->_schedctl = (void *) schedctl_init () ; |
885 thread->_schedctl = (void *) schedctl_init(); |
886 |
886 |
887 if (UseNUMA) { |
887 if (UseNUMA) { |
888 int lgrp_id = os::numa_get_group_id(); |
888 int lgrp_id = os::numa_get_group_id(); |
889 if (lgrp_id != -1) { |
889 if (lgrp_id != -1) { |
890 thread->set_lgrp_id(lgrp_id); |
890 thread->set_lgrp_id(lgrp_id); |
891 } |
891 } |
892 } |
892 } |
893 |
893 |
894 if ( ThreadPriorityVerbose ) { |
894 if (ThreadPriorityVerbose) { |
895 tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n", |
895 tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n", |
896 osthread->thread_id(), osthread->lwp_id() ); |
896 osthread->thread_id(), osthread->lwp_id()); |
897 } |
897 } |
898 |
898 |
899 // Initial thread state is INITIALIZED, not SUSPENDED |
899 // Initial thread state is INITIALIZED, not SUSPENDED |
900 osthread->set_state(INITIALIZED); |
900 osthread->set_state(INITIALIZED); |
901 |
901 |
972 OSThread* osthread = new OSThread(NULL, NULL); |
972 OSThread* osthread = new OSThread(NULL, NULL); |
973 if (osthread == NULL) { |
973 if (osthread == NULL) { |
974 return false; |
974 return false; |
975 } |
975 } |
976 |
976 |
977 if ( ThreadPriorityVerbose ) { |
977 if (ThreadPriorityVerbose) { |
978 char *thrtyp; |
978 char *thrtyp; |
979 switch ( thr_type ) { |
979 switch (thr_type) { |
980 case vm_thread: |
980 case vm_thread: |
981 thrtyp = (char *)"vm"; |
981 thrtyp = (char *)"vm"; |
982 break; |
982 break; |
983 case cgc_thread: |
983 case cgc_thread: |
984 thrtyp = (char *)"cgc"; |
984 thrtyp = (char *)"cgc"; |
1205 } |
1205 } |
1206 |
1206 |
1207 |
1207 |
1208 // First crack at OS-specific initialization, from inside the new thread. |
1208 // First crack at OS-specific initialization, from inside the new thread. |
1209 void os::initialize_thread(Thread* thr) { |
1209 void os::initialize_thread(Thread* thr) { |
1210 int r = thr_main() ; |
1210 int r = thr_main(); |
1211 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; |
1211 guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); |
1212 if (r) { |
1212 if (r) { |
1213 JavaThread* jt = (JavaThread *)thr; |
1213 JavaThread* jt = (JavaThread *)thr; |
1214 assert(jt != NULL,"Sanity check"); |
1214 assert(jt != NULL, "Sanity check"); |
1215 size_t stack_size; |
1215 size_t stack_size; |
1216 address base = jt->stack_base(); |
1216 address base = jt->stack_base(); |
1217 if (Arguments::created_by_java_launcher()) { |
1217 if (Arguments::created_by_java_launcher()) { |
1218 // Use 2MB to allow for Solaris 7 64 bit mode. |
1218 // Use 2MB to allow for Solaris 7 64 bit mode. |
1219 stack_size = JavaThread::stack_size_at_create() == 0 |
1219 stack_size = JavaThread::stack_size_at_create() == 0 |
1320 // interface. I think, however, that it will be faster to |
1320 // interface. I think, however, that it will be faster to |
1321 // maintain the invariant that %g2 always contains the |
1321 // maintain the invariant that %g2 always contains the |
1322 // JavaThread in Java code, and have stubs simply |
1322 // JavaThread in Java code, and have stubs simply |
1323 // treat %g2 as a caller-save register, preserving it in a %lN. |
1323 // treat %g2 as a caller-save register, preserving it in a %lN. |
1324 thread_key_t tk; |
1324 thread_key_t tk; |
1325 if (thr_keycreate( &tk, NULL ) ) |
1325 if (thr_keycreate( &tk, NULL)) |
1326 fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed " |
1326 fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed " |
1327 "(%s)", strerror(errno))); |
1327 "(%s)", strerror(errno))); |
1328 return int(tk); |
1328 return int(tk); |
1329 } |
1329 } |
1330 |
1330 |
1345 } else { |
1345 } else { |
1346 fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed " |
1346 fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed " |
1347 "(%s)", strerror(errno))); |
1347 "(%s)", strerror(errno))); |
1348 } |
1348 } |
1349 } else { |
1349 } else { |
1350 ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ; |
1350 ThreadLocalStorage::set_thread_in_slot((Thread *) value); |
1351 } |
1351 } |
1352 } |
1352 } |
1353 |
1353 |
1354 // This function could be called before TLS is initialized, for example, when |
1354 // This function could be called before TLS is initialized, for example, when |
1355 // VM receives an async signal or when VM causes a fatal error during |
1355 // VM receives an async signal or when VM causes a fatal error during |
1577 int n; |
1577 int n; |
1578 char** pelements = split_path(pname, &n); |
1578 char** pelements = split_path(pname, &n); |
1579 if (pelements == NULL) { |
1579 if (pelements == NULL) { |
1580 return false; |
1580 return false; |
1581 } |
1581 } |
1582 for (int i = 0 ; i < n ; i++) { |
1582 for (int i = 0; i < n; i++) { |
1583 // really shouldn't be NULL but what the heck, check can't hurt |
1583 // really shouldn't be NULL but what the heck, check can't hurt |
1584 if (pelements[i] == NULL || strlen(pelements[i]) == 0) { |
1584 if (pelements[i] == NULL || strlen(pelements[i]) == 0) { |
1585 continue; // skip the empty path values |
1585 continue; // skip the empty path values |
1586 } |
1586 } |
1587 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); |
1587 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); |
1589 retval = true; |
1589 retval = true; |
1590 break; |
1590 break; |
1591 } |
1591 } |
1592 } |
1592 } |
1593 // release the storage |
1593 // release the storage |
1594 for (int i = 0 ; i < n ; i++) { |
1594 for (int i = 0; i < n; i++) { |
1595 if (pelements[i] != NULL) { |
1595 if (pelements[i] != NULL) { |
1596 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); |
1596 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); |
1597 } |
1597 } |
1598 } |
1598 } |
1599 if (pelements != NULL) { |
1599 if (pelements != NULL) { |
1793 return NULL; |
1793 return NULL; |
1794 } |
1794 } |
1795 |
1795 |
1796 bool failed_to_read_elf_head= |
1796 bool failed_to_read_elf_head= |
1797 (sizeof(elf_head)!= |
1797 (sizeof(elf_head)!= |
1798 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ; |
1798 (::read(file_descriptor, &elf_head,sizeof(elf_head)))); |
1799 |
1799 |
1800 ::close(file_descriptor); |
1800 ::close(file_descriptor); |
1801 if (failed_to_read_elf_head) { |
1801 if (failed_to_read_elf_head) { |
1802 // file i/o error - report dlerror() msg |
1802 // file i/o error - report dlerror() msg |
1803 return NULL; |
1803 return NULL; |
1849 // Obtain string descriptions for architectures |
1849 // Obtain string descriptions for architectures |
1850 |
1850 |
1851 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; |
1851 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; |
1852 int running_arch_index=-1; |
1852 int running_arch_index=-1; |
1853 |
1853 |
1854 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) { |
1854 for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) { |
1855 if (running_arch_code == arch_array[i].code) { |
1855 if (running_arch_code == arch_array[i].code) { |
1856 running_arch_index = i; |
1856 running_arch_index = i; |
1857 } |
1857 } |
1858 if (lib_arch.code == arch_array[i].code) { |
1858 if (lib_arch.code == arch_array[i].code) { |
1859 lib_arch.compat_class = arch_array[i].compat_class; |
1859 lib_arch.compat_class = arch_array[i].compat_class; |
1878 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); |
1878 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); |
1879 return NULL; |
1879 return NULL; |
1880 } |
1880 } |
1881 |
1881 |
1882 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { |
1882 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { |
1883 if ( lib_arch.name!=NULL ) { |
1883 if (lib_arch.name!=NULL) { |
1884 ::snprintf(diag_msg_buf, diag_msg_max_length-1, |
1884 ::snprintf(diag_msg_buf, diag_msg_max_length-1, |
1885 " (Possible cause: can't load %s-bit .so on a %s-bit platform)", |
1885 " (Possible cause: can't load %s-bit .so on a %s-bit platform)", |
1886 lib_arch.name, arch_array[running_arch_index].name); |
1886 lib_arch.name, arch_array[running_arch_index].name); |
1887 } else { |
1887 } else { |
1888 ::snprintf(diag_msg_buf, diag_msg_max_length-1, |
1888 ::snprintf(diag_msg_buf, diag_msg_max_length-1, |
1967 static bool check_addr0(outputStream* st) { |
1967 static bool check_addr0(outputStream* st) { |
1968 jboolean status = false; |
1968 jboolean status = false; |
1969 int fd = ::open("/proc/self/map",O_RDONLY); |
1969 int fd = ::open("/proc/self/map",O_RDONLY); |
1970 if (fd >= 0) { |
1970 if (fd >= 0) { |
1971 prmap_t p; |
1971 prmap_t p; |
1972 while(::read(fd, &p, sizeof(p)) > 0) { |
1972 while (::read(fd, &p, sizeof(p)) > 0) { |
1973 if (p.pr_vaddr == 0x0) { |
1973 if (p.pr_vaddr == 0x0) { |
1974 st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname); |
1974 st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname); |
1975 st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname); |
1975 st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname); |
1976 st->print("Access:"); |
1976 st->print("Access:"); |
1977 st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-"); |
1977 st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-"); |
2077 st->print(", sa_mask[0]="); |
2077 st->print(", sa_mask[0]="); |
2078 os::Posix::print_signal_set_short(st, &sa.sa_mask); |
2078 os::Posix::print_signal_set_short(st, &sa.sa_mask); |
2079 |
2079 |
2080 address rh = VMError::get_resetted_sighandler(sig); |
2080 address rh = VMError::get_resetted_sighandler(sig); |
2081 // May be, handler was resetted by VMError? |
2081 // May be, handler was resetted by VMError? |
2082 if(rh != NULL) { |
2082 if (rh != NULL) { |
2083 handler = rh; |
2083 handler = rh; |
2084 sa.sa_flags = VMError::get_resetted_sigflags(sig); |
2084 sa.sa_flags = VMError::get_resetted_sigflags(sig); |
2085 } |
2085 } |
2086 |
2086 |
2087 st->print(", sa_flags="); |
2087 st->print(", sa_flags="); |
2088 os::Posix::print_sa_flags(st, sa.sa_flags); |
2088 os::Posix::print_sa_flags(st, sa.sa_flags); |
2089 |
2089 |
2090 // Check: is it our handler? |
2090 // Check: is it our handler? |
2091 if(handler == CAST_FROM_FN_PTR(address, signalHandler) || |
2091 if (handler == CAST_FROM_FN_PTR(address, signalHandler) || |
2092 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) { |
2092 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) { |
2093 // It is our signal handler |
2093 // It is our signal handler |
2094 // check for flags |
2094 // check for flags |
2095 if(sa.sa_flags != os::Solaris::get_our_sigflags(sig)) { |
2095 if (sa.sa_flags != os::Solaris::get_our_sigflags(sig)) { |
2096 st->print( |
2096 st->print( |
2097 ", flags was changed from " PTR32_FORMAT ", consider using jsig library", |
2097 ", flags was changed from " PTR32_FORMAT ", consider using jsig library", |
2098 os::Solaris::get_our_sigflags(sig)); |
2098 os::Solaris::get_our_sigflags(sig)); |
2099 } |
2099 } |
2100 } |
2100 } |
2401 |
2401 |
2402 bool threadIsSuspended; |
2402 bool threadIsSuspended; |
2403 do { |
2403 do { |
2404 thread->set_suspend_equivalent(); |
2404 thread->set_suspend_equivalent(); |
2405 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() |
2405 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() |
2406 while((ret = ::sema_wait(&sig_sem)) == EINTR) |
2406 while ((ret = ::sema_wait(&sig_sem)) == EINTR) |
2407 ; |
2407 ; |
2408 assert(ret == 0, "sema_wait() failed"); |
2408 assert(ret == 0, "sema_wait() failed"); |
2409 |
2409 |
2410 // were we externally suspended while we were waiting? |
2410 // were we externally suspended while we were waiting? |
2411 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
2411 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); |
2633 ids[0] = 0; |
2633 ids[0] = 0; |
2634 return 1; |
2634 return 1; |
2635 } |
2635 } |
2636 if (!r) { |
2636 if (!r) { |
2637 // That's a leaf node. |
2637 // That's a leaf node. |
2638 assert (bottom <= cur, "Sanity check"); |
2638 assert(bottom <= cur, "Sanity check"); |
2639 // Check if the node has memory |
2639 // Check if the node has memory |
2640 if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur], |
2640 if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur], |
2641 NULL, 0, LGRP_RSRC_MEM) > 0) { |
2641 NULL, 0, LGRP_RSRC_MEM) > 0) { |
2642 ids[bottom++] = ids[cur]; |
2642 ids[bottom++] = ids[cur]; |
2643 } |
2643 } |
3049 // account. |
3049 // account. |
3050 insertion_sort_descending(_page_sizes, n); |
3050 insertion_sort_descending(_page_sizes, n); |
3051 const size_t size_limit = |
3051 const size_t size_limit = |
3052 FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes; |
3052 FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes; |
3053 int beg; |
3053 int beg; |
3054 for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */ ; |
3054 for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */; |
3055 const int end = MIN2((int)usable_count, n) - 1; |
3055 const int end = MIN2((int)usable_count, n) - 1; |
3056 for (int cur = 0; cur < end; ++cur, ++beg) { |
3056 for (int cur = 0; cur < end; ++cur, ++beg) { |
3057 _page_sizes[cur] = _page_sizes[beg]; |
3057 _page_sizes[cur] = _page_sizes[beg]; |
3058 } |
3058 } |
3059 _page_sizes[end] = vm_page_size(); |
3059 _page_sizes[end] = vm_page_size(); |
3262 // |
3262 // |
3263 // Try to determine the priority scale for our process. |
3263 // Try to determine the priority scale for our process. |
3264 // |
3264 // |
3265 // Return errno or 0 if OK. |
3265 // Return errno or 0 if OK. |
3266 // |
3266 // |
3267 static int lwp_priocntl_init () { |
3267 static int lwp_priocntl_init() { |
3268 int rslt; |
3268 int rslt; |
3269 pcinfo_t ClassInfo; |
3269 pcinfo_t ClassInfo; |
3270 pcparms_t ParmInfo; |
3270 pcparms_t ParmInfo; |
3271 int i; |
3271 int i; |
3272 |
3272 |
3273 if (!UseThreadPriorities) return 0; |
3273 if (!UseThreadPriorities) return 0; |
3274 |
3274 |
3275 // If ThreadPriorityPolicy is 1, switch tables |
3275 // If ThreadPriorityPolicy is 1, switch tables |
3276 if (ThreadPriorityPolicy == 1) { |
3276 if (ThreadPriorityPolicy == 1) { |
3277 for (i = 0 ; i < CriticalPriority+1; i++) |
3277 for (i = 0; i < CriticalPriority+1; i++) |
3278 os::java_to_os_priority[i] = prio_policy1[i]; |
3278 os::java_to_os_priority[i] = prio_policy1[i]; |
3279 } |
3279 } |
3280 if (UseCriticalJavaThreadPriority) { |
3280 if (UseCriticalJavaThreadPriority) { |
3281 // MaxPriority always maps to the FX scheduling class and criticalPrio. |
3281 // MaxPriority always maps to the FX scheduling class and criticalPrio. |
3282 // See set_native_priority() and set_lwp_class_and_priority(). |
3282 // See set_native_priority() and set_lwp_class_and_priority(). |
3371 myMax = fxLimits.maxPrio; |
3371 myMax = fxLimits.maxPrio; |
3372 myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict |
3372 myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict |
3373 } else { |
3373 } else { |
3374 // No clue - punt |
3374 // No clue - punt |
3375 if (ThreadPriorityVerbose) |
3375 if (ThreadPriorityVerbose) |
3376 tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname); |
3376 tty->print_cr("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname); |
3377 return EINVAL; // no clue, punt |
3377 return EINVAL; // no clue, punt |
3378 } |
3378 } |
3379 |
3379 |
3380 if (ThreadPriorityVerbose) { |
3380 if (ThreadPriorityVerbose) { |
3381 tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax); |
3381 tty->print_cr("Thread priority Range: [%d..%d]\n", myMin, myMax); |
3382 } |
3382 } |
3383 |
3383 |
3384 priocntl_enable = true; // Enable changing priorities |
3384 priocntl_enable = true; // Enable changing priorities |
3385 return 0; |
3385 return 0; |
3386 } |
3386 } |
3422 // TODO: accelerate this by eliminating the PC_GETPARMS call. |
3422 // TODO: accelerate this by eliminating the PC_GETPARMS call. |
3423 // Cache "pcparms_t" in global ParmCache. |
3423 // Cache "pcparms_t" in global ParmCache. |
3424 // TODO: elide set-to-same-value |
3424 // TODO: elide set-to-same-value |
3425 |
3425 |
3426 // If something went wrong on init, don't change priorities. |
3426 // If something went wrong on init, don't change priorities. |
3427 if ( !priocntl_enable ) { |
3427 if (!priocntl_enable) { |
3428 if (ThreadPriorityVerbose) |
3428 if (ThreadPriorityVerbose) |
3429 tty->print_cr("Trying to set priority but init failed, ignoring"); |
3429 tty->print_cr("Trying to set priority but init failed, ignoring"); |
3430 return EINVAL; |
3430 return EINVAL; |
3431 } |
3431 } |
3432 |
3432 |
3433 // If lwp hasn't started yet, just return |
3433 // If lwp hasn't started yet, just return |
3434 // the _start routine will call us again. |
3434 // the _start routine will call us again. |
3435 if ( lwpid <= 0 ) { |
3435 if (lwpid <= 0) { |
3436 if (ThreadPriorityVerbose) { |
3436 if (ThreadPriorityVerbose) { |
3437 tty->print_cr ("deferring the set_lwp_class_and_priority of thread " |
3437 tty->print_cr("deferring the set_lwp_class_and_priority of thread " |
3438 INTPTR_FORMAT " to %d, lwpid not set", |
3438 INTPTR_FORMAT " to %d, lwpid not set", |
3439 ThreadID, newPrio); |
3439 ThreadID, newPrio); |
3440 } |
3440 } |
3441 return 0; |
3441 return 0; |
3442 } |
3442 } |
3651 } |
3651 } |
3652 |
3652 |
3653 |
3653 |
3654 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { |
3654 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { |
3655 int p; |
3655 int p; |
3656 if ( !UseThreadPriorities ) { |
3656 if (!UseThreadPriorities) { |
3657 *priority_ptr = NormalPriority; |
3657 *priority_ptr = NormalPriority; |
3658 return OS_OK; |
3658 return OS_OK; |
3659 } |
3659 } |
3660 int status = thr_getprio(thread->osthread()->thread_id(), &p); |
3660 int status = thr_getprio(thread->osthread()->thread_id(), &p); |
3661 if (status != 0) { |
3661 if (status != 0) { |
4097 // under CheckJNI, we can add any periodic checks here |
4097 // under CheckJNI, we can add any periodic checks here |
4098 |
4098 |
4099 void os::run_periodic_checks() { |
4099 void os::run_periodic_checks() { |
4100 // A big source of grief is hijacking virt. addr 0x0 on Solaris, |
4100 // A big source of grief is hijacking virt. addr 0x0 on Solaris, |
4101 // thereby preventing a NULL checks. |
4101 // thereby preventing a NULL checks. |
4102 if(!check_addr0_done) check_addr0_done = check_addr0(tty); |
4102 if (!check_addr0_done) check_addr0_done = check_addr0(tty); |
4103 |
4103 |
4104 if (check_signals == false) return; |
4104 if (check_signals == false) return; |
4105 |
4105 |
4106 // SEGV and BUS if overridden could potentially prevent |
4106 // SEGV and BUS if overridden could potentially prevent |
4107 // generation of hs*.log in the event of a crash, debugging |
4107 // generation of hs*.log in the event of a crash, debugging |
4146 |
4146 |
4147 os_sigaction(sig, (struct sigaction*)NULL, &act); |
4147 os_sigaction(sig, (struct sigaction*)NULL, &act); |
4148 |
4148 |
4149 address thisHandler = (act.sa_flags & SA_SIGINFO) |
4149 address thisHandler = (act.sa_flags & SA_SIGINFO) |
4150 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) |
4150 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) |
4151 : CAST_FROM_FN_PTR(address, act.sa_handler) ; |
4151 : CAST_FROM_FN_PTR(address, act.sa_handler); |
4152 |
4152 |
4153 |
4153 |
4154 switch(sig) { |
4154 switch (sig) { |
4155 case SIGSEGV: |
4155 case SIGSEGV: |
4156 case SIGBUS: |
4156 case SIGBUS: |
4157 case SIGFPE: |
4157 case SIGFPE: |
4158 case SIGPIPE: |
4158 case SIGPIPE: |
4159 case SIGXFSZ: |
4159 case SIGXFSZ: |
4330 // (Static) wrapper for meminfo() call. |
4330 // (Static) wrapper for meminfo() call. |
4331 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0; |
4331 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0; |
4332 |
4332 |
4333 static address resolve_symbol_lazy(const char* name) { |
4333 static address resolve_symbol_lazy(const char* name) { |
4334 address addr = (address) dlsym(RTLD_DEFAULT, name); |
4334 address addr = (address) dlsym(RTLD_DEFAULT, name); |
4335 if(addr == NULL) { |
4335 if (addr == NULL) { |
4336 // RTLD_DEFAULT was not defined on some early versions of 2.5.1 |
4336 // RTLD_DEFAULT was not defined on some early versions of 2.5.1 |
4337 addr = (address) dlsym(RTLD_NEXT, name); |
4337 addr = (address) dlsym(RTLD_NEXT, name); |
4338 } |
4338 } |
4339 return addr; |
4339 return addr; |
4340 } |
4340 } |
4341 |
4341 |
4342 static address resolve_symbol(const char* name) { |
4342 static address resolve_symbol(const char* name) { |
4343 address addr = resolve_symbol_lazy(name); |
4343 address addr = resolve_symbol_lazy(name); |
4344 if(addr == NULL) { |
4344 if (addr == NULL) { |
4345 fatal(dlerror()); |
4345 fatal(dlerror()); |
4346 } |
4346 } |
4347 return addr; |
4347 return addr; |
4348 } |
4348 } |
4349 |
4349 |
4351 address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); |
4351 address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); |
4352 |
4352 |
4353 lwp_priocntl_init(); |
4353 lwp_priocntl_init(); |
4354 |
4354 |
4355 // RTLD_DEFAULT was not defined on some early versions of 5.5.1 |
4355 // RTLD_DEFAULT was not defined on some early versions of 5.5.1 |
4356 if(func == NULL) { |
4356 if (func == NULL) { |
4357 func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators"); |
4357 func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators"); |
4358 // Guarantee that this VM is running on an new enough OS (5.6 or |
4358 // Guarantee that this VM is running on an new enough OS (5.6 or |
4359 // later) that it will have a new enough libthread.so. |
4359 // later) that it will have a new enough libthread.so. |
4360 guarantee(func != NULL, "libthread.so is too old."); |
4360 guarantee(func != NULL, "libthread.so is too old."); |
4361 } |
4361 } |
4382 int_fnP_cond_tP_i_vP os::Solaris::_cond_init; |
4382 int_fnP_cond_tP_i_vP os::Solaris::_cond_init; |
4383 int_fnP_cond_tP os::Solaris::_cond_destroy; |
4383 int_fnP_cond_tP os::Solaris::_cond_destroy; |
4384 int os::Solaris::_cond_scope = USYNC_THREAD; |
4384 int os::Solaris::_cond_scope = USYNC_THREAD; |
4385 |
4385 |
4386 void os::Solaris::synchronization_init() { |
4386 void os::Solaris::synchronization_init() { |
4387 if(UseLWPSynchronization) { |
4387 if (UseLWPSynchronization) { |
4388 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock"))); |
4388 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock"))); |
4389 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock"))); |
4389 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock"))); |
4390 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock"))); |
4390 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock"))); |
4391 os::Solaris::set_mutex_init(lwp_mutex_init); |
4391 os::Solaris::set_mutex_init(lwp_mutex_init); |
4392 os::Solaris::set_mutex_destroy(lwp_mutex_destroy); |
4392 os::Solaris::set_mutex_destroy(lwp_mutex_destroy); |
4402 } |
4402 } |
4403 else { |
4403 else { |
4404 os::Solaris::set_mutex_scope(USYNC_THREAD); |
4404 os::Solaris::set_mutex_scope(USYNC_THREAD); |
4405 os::Solaris::set_cond_scope(USYNC_THREAD); |
4405 os::Solaris::set_cond_scope(USYNC_THREAD); |
4406 |
4406 |
4407 if(UsePthreads) { |
4407 if (UsePthreads) { |
4408 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock"))); |
4408 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock"))); |
4409 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock"))); |
4409 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock"))); |
4410 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock"))); |
4410 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock"))); |
4411 os::Solaris::set_mutex_init(pthread_mutex_default_init); |
4411 os::Solaris::set_mutex_init(pthread_mutex_default_init); |
4412 os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy"))); |
4412 os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy"))); |
4574 } |
4574 } |
4575 |
4575 |
4576 os::set_polling_page(polling_page); |
4576 os::set_polling_page(polling_page); |
4577 |
4577 |
4578 #ifndef PRODUCT |
4578 #ifndef PRODUCT |
4579 if( Verbose && PrintMiscellaneous ) |
4579 if (Verbose && PrintMiscellaneous) |
4580 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); |
4580 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); |
4581 #endif |
4581 #endif |
4582 |
4582 |
4583 if (!UseMembar) { |
4583 if (!UseMembar) { |
4584 address mem_serialize_page = (address)Solaris::mmap_chunk( NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE ); |
4584 address mem_serialize_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE); |
4585 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); |
4585 guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); |
4586 os::set_memory_serialize_page( mem_serialize_page ); |
4586 os::set_memory_serialize_page(mem_serialize_page); |
4587 |
4587 |
4588 #ifndef PRODUCT |
4588 #ifndef PRODUCT |
4589 if(Verbose && PrintMiscellaneous) |
4589 if (Verbose && PrintMiscellaneous) |
4590 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); |
4590 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); |
4591 #endif |
4591 #endif |
4592 } |
4592 } |
4593 |
4593 |
4594 // Check minimum allowable stack size for thread creation and to initialize |
4594 // Check minimum allowable stack size for thread creation and to initialize |
4723 return; |
4723 return; |
4724 } |
4724 } |
4725 |
4725 |
4726 // Mark the polling page as unreadable |
4726 // Mark the polling page as unreadable |
4727 void os::make_polling_page_unreadable(void) { |
4727 void os::make_polling_page_unreadable(void) { |
4728 if( mprotect((char *)_polling_page, page_size, PROT_NONE) != 0 ) |
4728 if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) |
4729 fatal("Could not disable polling page"); |
4729 fatal("Could not disable polling page"); |
4730 }; |
4730 }; |
4731 |
4731 |
4732 // Mark the polling page as readable |
4732 // Mark the polling page as readable |
4733 void os::make_polling_page_readable(void) { |
4733 void os::make_polling_page_readable(void) { |
4734 if( mprotect((char *)_polling_page, page_size, PROT_READ) != 0 ) |
4734 if (mprotect((char *)_polling_page, page_size, PROT_READ) != 0) |
4735 fatal("Could not enable polling page"); |
4735 fatal("Could not enable polling page"); |
4736 }; |
4736 }; |
4737 |
4737 |
4738 // OS interface. |
4738 // OS interface. |
4739 |
4739 |
5219 |
5219 |
5220 sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage", |
5220 sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage", |
5221 getpid(), |
5221 getpid(), |
5222 thread->osthread()->lwp_id()); |
5222 thread->osthread()->lwp_id()); |
5223 fd = ::open(proc_name, O_RDONLY); |
5223 fd = ::open(proc_name, O_RDONLY); |
5224 if ( fd == -1 ) return -1; |
5224 if (fd == -1) return -1; |
5225 |
5225 |
5226 do { |
5226 do { |
5227 count = ::pread(fd, |
5227 count = ::pread(fd, |
5228 (void *)&prusage.pr_utime, |
5228 (void *)&prusage.pr_utime, |
5229 thr_time_size, |
5229 thr_time_size, |
5230 thr_time_off); |
5230 thr_time_off); |
5231 } while (count < 0 && errno == EINTR); |
5231 } while (count < 0 && errno == EINTR); |
5232 ::close(fd); |
5232 ::close(fd); |
5233 if ( count < 0 ) return -1; |
5233 if (count < 0) return -1; |
5234 |
5234 |
5235 if (user_sys_cpu_time) { |
5235 if (user_sys_cpu_time) { |
5236 // user + system CPU time |
5236 // user + system CPU time |
5237 lwp_time = (((jlong)prusage.pr_stime.tv_sec + |
5237 lwp_time = (((jlong)prusage.pr_stime.tv_sec + |
5238 (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) + |
5238 (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) + |
5242 // user level CPU time only |
5242 // user level CPU time only |
5243 lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) + |
5243 lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) + |
5244 (jlong)prusage.pr_utime.tv_nsec; |
5244 (jlong)prusage.pr_utime.tv_nsec; |
5245 } |
5245 } |
5246 |
5246 |
5247 return(lwp_time); |
5247 return (lwp_time); |
5248 } |
5248 } |
5249 |
5249 |
5250 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { |
5250 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { |
5251 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits |
5251 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits |
5252 info_ptr->may_skip_backward = false; // elapsed time not wall time |
5252 info_ptr->may_skip_backward = false; // elapsed time not wall time |
5446 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. |
5446 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. |
5447 // Conceptually TryPark() should be equivalent to park(0). |
5447 // Conceptually TryPark() should be equivalent to park(0). |
5448 |
5448 |
5449 int os::PlatformEvent::TryPark() { |
5449 int os::PlatformEvent::TryPark() { |
5450 for (;;) { |
5450 for (;;) { |
5451 const int v = _Event ; |
5451 const int v = _Event; |
5452 guarantee ((v == 0) || (v == 1), "invariant") ; |
5452 guarantee((v == 0) || (v == 1), "invariant"); |
5453 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ; |
5453 if (Atomic::cmpxchg(0, &_Event, v) == v) return v; |
5454 } |
5454 } |
5455 } |
5455 } |
5456 |
5456 |
5457 void os::PlatformEvent::park() { // AKA: down() |
5457 void os::PlatformEvent::park() { // AKA: down() |
5458 // Invariant: Only the thread associated with the Event/PlatformEvent |
5458 // Invariant: Only the thread associated with the Event/PlatformEvent |
5459 // may call park(). |
5459 // may call park(). |
5460 int v ; |
5460 int v; |
5461 for (;;) { |
5461 for (;;) { |
5462 v = _Event ; |
5462 v = _Event; |
5463 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; |
5463 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5464 } |
5464 } |
5465 guarantee (v >= 0, "invariant") ; |
5465 guarantee(v >= 0, "invariant"); |
5466 if (v == 0) { |
5466 if (v == 0) { |
5467 // Do this the hard way by blocking ... |
5467 // Do this the hard way by blocking ... |
5468 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5468 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5469 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. |
5469 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. |
5470 // Only for SPARC >= V8PlusA |
5470 // Only for SPARC >= V8PlusA |
5471 #if defined(__sparc) && defined(COMPILER2) |
5471 #if defined(__sparc) && defined(COMPILER2) |
5472 if (ClearFPUAtPark) { _mark_fpu_nosave() ; } |
5472 if (ClearFPUAtPark) { _mark_fpu_nosave(); } |
5473 #endif |
5473 #endif |
5474 int status = os::Solaris::mutex_lock(_mutex); |
5474 int status = os::Solaris::mutex_lock(_mutex); |
5475 assert_status(status == 0, status, "mutex_lock"); |
5475 assert_status(status == 0, status, "mutex_lock"); |
5476 guarantee (_nParked == 0, "invariant") ; |
5476 guarantee(_nParked == 0, "invariant"); |
5477 ++ _nParked ; |
5477 ++_nParked; |
5478 while (_Event < 0) { |
5478 while (_Event < 0) { |
5479 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... |
5479 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... |
5480 // Treat this the same as if the wait was interrupted |
5480 // Treat this the same as if the wait was interrupted |
5481 // With usr/lib/lwp going to kernel, always handle ETIME |
5481 // With usr/lib/lwp going to kernel, always handle ETIME |
5482 status = os::Solaris::cond_wait(_cond, _mutex); |
5482 status = os::Solaris::cond_wait(_cond, _mutex); |
5483 if (status == ETIME) status = EINTR ; |
5483 if (status == ETIME) status = EINTR; |
5484 assert_status(status == 0 || status == EINTR, status, "cond_wait"); |
5484 assert_status(status == 0 || status == EINTR, status, "cond_wait"); |
5485 } |
5485 } |
5486 -- _nParked ; |
5486 --_nParked; |
5487 _Event = 0 ; |
5487 _Event = 0; |
5488 status = os::Solaris::mutex_unlock(_mutex); |
5488 status = os::Solaris::mutex_unlock(_mutex); |
5489 assert_status(status == 0, status, "mutex_unlock"); |
5489 assert_status(status == 0, status, "mutex_unlock"); |
5490 // Paranoia to ensure our locked and lock-free paths interact |
5490 // Paranoia to ensure our locked and lock-free paths interact |
5491 // correctly with each other. |
5491 // correctly with each other. |
5492 OrderAccess::fence(); |
5492 OrderAccess::fence(); |
5493 } |
5493 } |
5494 } |
5494 } |
5495 |
5495 |
5496 int os::PlatformEvent::park(jlong millis) { |
5496 int os::PlatformEvent::park(jlong millis) { |
5497 guarantee (_nParked == 0, "invariant") ; |
5497 guarantee(_nParked == 0, "invariant"); |
5498 int v ; |
5498 int v; |
5499 for (;;) { |
5499 for (;;) { |
5500 v = _Event ; |
5500 v = _Event; |
5501 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; |
5501 if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; |
5502 } |
5502 } |
5503 guarantee (v >= 0, "invariant") ; |
5503 guarantee(v >= 0, "invariant"); |
5504 if (v != 0) return OS_OK ; |
5504 if (v != 0) return OS_OK; |
5505 |
5505 |
5506 int ret = OS_TIMEOUT; |
5506 int ret = OS_TIMEOUT; |
5507 timestruc_t abst; |
5507 timestruc_t abst; |
5508 compute_abstime (&abst, millis); |
5508 compute_abstime(&abst, millis); |
5509 |
5509 |
5510 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5510 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5511 // For Solaris SPARC set fprs.FEF=0 prior to parking. |
5511 // For Solaris SPARC set fprs.FEF=0 prior to parking. |
5512 // Only for SPARC >= V8PlusA |
5512 // Only for SPARC >= V8PlusA |
5513 #if defined(__sparc) && defined(COMPILER2) |
5513 #if defined(__sparc) && defined(COMPILER2) |
5514 if (ClearFPUAtPark) { _mark_fpu_nosave() ; } |
5514 if (ClearFPUAtPark) { _mark_fpu_nosave(); } |
5515 #endif |
5515 #endif |
5516 int status = os::Solaris::mutex_lock(_mutex); |
5516 int status = os::Solaris::mutex_lock(_mutex); |
5517 assert_status(status == 0, status, "mutex_lock"); |
5517 assert_status(status == 0, status, "mutex_lock"); |
5518 guarantee (_nParked == 0, "invariant") ; |
5518 guarantee(_nParked == 0, "invariant"); |
5519 ++ _nParked ; |
5519 ++_nParked; |
5520 while (_Event < 0) { |
5520 while (_Event < 0) { |
5521 int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst); |
5521 int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst); |
5522 assert_status(status == 0 || status == EINTR || |
5522 assert_status(status == 0 || status == EINTR || |
5523 status == ETIME || status == ETIMEDOUT, |
5523 status == ETIME || status == ETIMEDOUT, |
5524 status, "cond_timedwait"); |
5524 status, "cond_timedwait"); |
5525 if (!FilterSpuriousWakeups) break ; // previous semantics |
5525 if (!FilterSpuriousWakeups) break; // previous semantics |
5526 if (status == ETIME || status == ETIMEDOUT) break ; |
5526 if (status == ETIME || status == ETIMEDOUT) break; |
5527 // We consume and ignore EINTR and spurious wakeups. |
5527 // We consume and ignore EINTR and spurious wakeups. |
5528 } |
5528 } |
5529 -- _nParked ; |
5529 --_nParked; |
5530 if (_Event >= 0) ret = OS_OK ; |
5530 if (_Event >= 0) ret = OS_OK; |
5531 _Event = 0 ; |
5531 _Event = 0; |
5532 status = os::Solaris::mutex_unlock(_mutex); |
5532 status = os::Solaris::mutex_unlock(_mutex); |
5533 assert_status(status == 0, status, "mutex_unlock"); |
5533 assert_status(status == 0, status, "mutex_unlock"); |
5534 // Paranoia to ensure our locked and lock-free paths interact |
5534 // Paranoia to ensure our locked and lock-free paths interact |
5535 // correctly with each other. |
5535 // correctly with each other. |
5536 OrderAccess::fence(); |
5536 OrderAccess::fence(); |
5603 * ignore overflow and just impose a hard-limit on seconds using the value |
5603 * ignore overflow and just impose a hard-limit on seconds using the value |
5604 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 |
5604 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 |
5605 * years from "now". |
5605 * years from "now". |
5606 */ |
5606 */ |
5607 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { |
5607 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { |
5608 assert (time > 0, "convertTime"); |
5608 assert(time > 0, "convertTime"); |
5609 |
5609 |
5610 struct timeval now; |
5610 struct timeval now; |
5611 int status = gettimeofday(&now, NULL); |
5611 int status = gettimeofday(&now, NULL); |
5612 assert(status == 0, "gettimeofday"); |
5612 assert(status == 0, "gettimeofday"); |
5613 |
5613 |
5662 return; |
5662 return; |
5663 } |
5663 } |
5664 |
5664 |
5665 // First, demultiplex/decode time arguments |
5665 // First, demultiplex/decode time arguments |
5666 timespec absTime; |
5666 timespec absTime; |
5667 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all |
5667 if (time < 0 || (isAbsolute && time == 0)) { // don't wait at all |
5668 return; |
5668 return; |
5669 } |
5669 } |
5670 if (time > 0) { |
5670 if (time > 0) { |
5671 // Warning: this code might be exposed to the old Solaris time |
5671 // Warning: this code might be exposed to the old Solaris time |
5672 // round-down bugs. Grep "roundingFix" for details. |
5672 // round-down bugs. Grep "roundingFix" for details. |
5686 if (Thread::is_interrupted(thread, false) || |
5686 if (Thread::is_interrupted(thread, false) || |
5687 os::Solaris::mutex_trylock(_mutex) != 0) { |
5687 os::Solaris::mutex_trylock(_mutex) != 0) { |
5688 return; |
5688 return; |
5689 } |
5689 } |
5690 |
5690 |
5691 int status ; |
5691 int status; |
5692 |
5692 |
5693 if (_counter > 0) { // no wait needed |
5693 if (_counter > 0) { // no wait needed |
5694 _counter = 0; |
5694 _counter = 0; |
5695 status = os::Solaris::mutex_unlock(_mutex); |
5695 status = os::Solaris::mutex_unlock(_mutex); |
5696 assert (status == 0, "invariant") ; |
5696 assert(status == 0, "invariant"); |
5697 // Paranoia to ensure our locked and lock-free paths interact |
5697 // Paranoia to ensure our locked and lock-free paths interact |
5698 // correctly with each other and Java-level accesses. |
5698 // correctly with each other and Java-level accesses. |
5699 OrderAccess::fence(); |
5699 OrderAccess::fence(); |
5700 return; |
5700 return; |
5701 } |
5701 } |
5715 // Do this the hard way by blocking ... |
5715 // Do this the hard way by blocking ... |
5716 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5716 // See http://monaco.sfbay/detail.jsf?cr=5094058. |
5717 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. |
5717 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. |
5718 // Only for SPARC >= V8PlusA |
5718 // Only for SPARC >= V8PlusA |
5719 #if defined(__sparc) && defined(COMPILER2) |
5719 #if defined(__sparc) && defined(COMPILER2) |
5720 if (ClearFPUAtPark) { _mark_fpu_nosave() ; } |
5720 if (ClearFPUAtPark) { _mark_fpu_nosave(); } |
5721 #endif |
5721 #endif |
5722 |
5722 |
5723 if (time == 0) { |
5723 if (time == 0) { |
5724 status = os::Solaris::cond_wait (_cond, _mutex) ; |
5724 status = os::Solaris::cond_wait(_cond, _mutex); |
5725 } else { |
5725 } else { |
5726 status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime); |
5726 status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime); |
5727 } |
5727 } |
5728 // Note that an untimed cond_wait() can sometimes return ETIME on older |
5728 // Note that an untimed cond_wait() can sometimes return ETIME on older |
5729 // versions of the Solaris. |
5729 // versions of the Solaris. |
5732 status, "cond_timedwait"); |
5732 status, "cond_timedwait"); |
5733 |
5733 |
5734 #ifdef ASSERT |
5734 #ifdef ASSERT |
5735 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL); |
5735 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL); |
5736 #endif |
5736 #endif |
5737 _counter = 0 ; |
5737 _counter = 0; |
5738 status = os::Solaris::mutex_unlock(_mutex); |
5738 status = os::Solaris::mutex_unlock(_mutex); |
5739 assert_status(status == 0, status, "mutex_unlock") ; |
5739 assert_status(status == 0, status, "mutex_unlock"); |
5740 // Paranoia to ensure our locked and lock-free paths interact |
5740 // Paranoia to ensure our locked and lock-free paths interact |
5741 // correctly with each other and Java-level accesses. |
5741 // correctly with each other and Java-level accesses. |
5742 OrderAccess::fence(); |
5742 OrderAccess::fence(); |
5743 |
5743 |
5744 // If externally suspended while waiting, re-suspend |
5744 // If externally suspended while waiting, re-suspend |
5746 jt->java_suspend_self(); |
5746 jt->java_suspend_self(); |
5747 } |
5747 } |
5748 } |
5748 } |
5749 |
5749 |
5750 void Parker::unpark() { |
5750 void Parker::unpark() { |
5751 int s, status ; |
5751 int s, status; |
5752 status = os::Solaris::mutex_lock (_mutex) ; |
5752 status = os::Solaris::mutex_lock(_mutex); |
5753 assert (status == 0, "invariant") ; |
5753 assert(status == 0, "invariant"); |
5754 s = _counter; |
5754 s = _counter; |
5755 _counter = 1; |
5755 _counter = 1; |
5756 status = os::Solaris::mutex_unlock (_mutex) ; |
5756 status = os::Solaris::mutex_unlock(_mutex); |
5757 assert (status == 0, "invariant") ; |
5757 assert(status == 0, "invariant"); |
5758 |
5758 |
5759 if (s < 1) { |
5759 if (s < 1) { |
5760 status = os::Solaris::cond_signal (_cond) ; |
5760 status = os::Solaris::cond_signal(_cond); |
5761 assert (status == 0, "invariant") ; |
5761 assert(status == 0, "invariant"); |
5762 } |
5762 } |
5763 } |
5763 } |
5764 |
5764 |
5765 extern char** environ; |
5765 extern char** environ; |
5766 |
5766 |
5923 "Assumed _thread_in_native"); |
5923 "Assumed _thread_in_native"); |
5924 |
5924 |
5925 gettimeofday(&t, &aNull); |
5925 gettimeofday(&t, &aNull); |
5926 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; |
5926 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; |
5927 |
5927 |
5928 for(;;) { |
5928 for (;;) { |
5929 res = ::poll(&pfd, 1, timeout); |
5929 res = ::poll(&pfd, 1, timeout); |
5930 if(res == OS_ERR && errno == EINTR) { |
5930 if (res == OS_ERR && errno == EINTR) { |
5931 if(timeout != -1) { |
5931 if (timeout != -1) { |
5932 gettimeofday(&t, &aNull); |
5932 gettimeofday(&t, &aNull); |
5933 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; |
5933 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; |
5934 timeout -= newtime - prevtime; |
5934 timeout -= newtime - prevtime; |
5935 if(timeout <= 0) |
5935 if (timeout <= 0) |
5936 return OS_OK; |
5936 return OS_OK; |
5937 prevtime = newtime; |
5937 prevtime = newtime; |
5938 } |
5938 } |
5939 } else return res; |
5939 } else return res; |
5940 } |
5940 } |