src/os/solaris/vm/os_solaris.inline.hpp

Wed, 27 Mar 2013 19:21:18 +0100

author
tschatzl
date
Wed, 27 Mar 2013 19:21:18 +0100
changeset 4854
754c24457b20
parent 4675
63e54c37ac64
child 5309
feae15578b2f
permissions
-rw-r--r--

7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
Summary: Ergonomics now also takes available virtual memory into account when deciding for a heap size. The helper method to determine the maximum allocatable memory block now uses the appropriate OS specific calls to retrieve available virtual memory for the java process. In 32 bit environments this method now also searches for the maximum actually reservable amount of memory. Merge previously separate implementations for Linux/BSD/Solaris into a single method.
Reviewed-by: jmasa, tamao

     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     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
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
    26 #define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP
    28 #include "runtime/atomic.inline.hpp"
    29 #include "runtime/os.hpp"
    31 #ifdef TARGET_OS_ARCH_solaris_x86
    32 # include "orderAccess_solaris_x86.inline.hpp"
    33 #endif
    34 #ifdef TARGET_OS_ARCH_solaris_sparc
    35 # include "orderAccess_solaris_sparc.inline.hpp"
    36 #endif
    38 // System includes
    39 #include <sys/param.h>
    40 #include <dlfcn.h>
    41 #include <sys/socket.h>
    42 #include <sys/poll.h>
    43 #include <sys/filio.h>
    44 #include <unistd.h>
    45 #include <netdb.h>
    46 #include <setjmp.h>
    48 inline const char* os::file_separator() { return "/"; }
    49 inline const char* os::line_separator() { return "\n"; }
    50 inline const char* os::path_separator() { return ":"; }
    52 // File names are case-sensitive on windows only
    53 inline int os::file_name_strcmp(const char* s1, const char* s2) {
    54   return strcmp(s1, s2);
    55 }
    57 inline bool os::uses_stack_guard_pages() {
    58   return true;
    59 }
    61 inline bool os::allocate_stack_guard_pages() {
    62   assert(uses_stack_guard_pages(), "sanity check");
    63   int r = thr_main() ;
    64   guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
    65   return r;
    66 }
    69 // On Solaris, reservations are made on a page by page basis, nothing to do.
    70 inline void os::pd_split_reserved_memory(char *base, size_t size,
    71                                       size_t split, bool realloc) {
    72 }
    75 // Bang the shadow pages if they need to be touched to be mapped.
    76 inline void os::bang_stack_shadow_pages() {
    77 }
    78 inline void os::dll_unload(void *lib) { ::dlclose(lib); }
    80 inline DIR* os::opendir(const char* dirname) {
    81   assert(dirname != NULL, "just checking");
    82   return ::opendir(dirname);
    83 }
    85 inline int os::readdir_buf_size(const char *path) {
    86   int size = pathconf(path, _PC_NAME_MAX);
    87   return (size < 0 ? MAXPATHLEN : size) + sizeof(dirent) + 1;
    88 }
    90 inline struct dirent* os::readdir(DIR* dirp, dirent* dbuf) {
    91   assert(dirp != NULL, "just checking");
    92 #if defined(_LP64) || defined(_GNU_SOURCE)
    93   dirent* p;
    94   int status;
    96   if((status = ::readdir_r(dirp, dbuf, &p)) != 0) {
    97     errno = status;
    98     return NULL;
    99   } else
   100     return p;
   101 #else  // defined(_LP64) || defined(_GNU_SOURCE)
   102   return ::readdir_r(dirp, dbuf);
   103 #endif // defined(_LP64) || defined(_GNU_SOURCE)
   104 }
   106 inline int os::closedir(DIR *dirp) {
   107   assert(dirp != NULL, "argument is NULL");
   108   return ::closedir(dirp);
   109 }
   111 //////////////////////////////////////////////////////////////////////////////
   112 ////////////////////////////////////////////////////////////////////////////////
   114 // macros for interruptible io and system calls and system call restarting
   116 #define _INTERRUPTIBLE(_setup, _cmd, _result, _thread, _clear, _before, _after, _int_enable) \
   117 do { \
   118   _setup; \
   119   _before; \
   120   OSThread* _osthread = _thread->osthread(); \
   121   if (_int_enable && _thread->has_last_Java_frame()) { \
   122     /* this is java interruptible io stuff */ \
   123     if (os::is_interrupted(_thread, _clear))  { \
   124       os::Solaris::bump_interrupted_before_count(); \
   125       _result = OS_INTRPT; \
   126     } else { \
   127       /* _cmd always expands to an assignment to _result */ \
   128       if ((_cmd) < 0 && errno == EINTR  \
   129        && os::is_interrupted(_thread, _clear)) { \
   130         os::Solaris::bump_interrupted_during_count(); \
   131         _result = OS_INTRPT; \
   132       } \
   133     } \
   134   } else { \
   135     /* this is normal blocking io stuff */ \
   136     _cmd; \
   137   } \
   138   _after; \
   139 } while(false)
   141 // Interruptible io support + restarting of interrupted system calls
   143 #ifndef ASSERT
   145 #define INTERRUPTIBLE(_cmd, _result, _clear) do { \
   146   _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO); \
   147 } while((_result == OS_ERR) && (errno == EINTR))
   149 #else
   151 // This adds an assertion that it is only called from thread_in_native
   152 // The call overhead is skipped for performance in product mode
   153 #define INTERRUPTIBLE(_cmd, _result, _clear) do { \
   154   _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO ); \
   155 } while((_result == OS_ERR) && (errno == EINTR))
   157 #endif
   159 // Used for calls from _thread_in_vm, not from _thread_in_native
   160 #define INTERRUPTIBLE_VM(_cmd, _result, _clear) do { \
   161   _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible(_thread), UseVMInterruptibleIO ); \
   162 } while((_result == OS_ERR) && (errno == EINTR))
   164 /* Use NORESTART when the system call cannot return EINTR, when something other
   165    than a system call is being invoked, or when the caller must do EINTR
   166    handling. */
   168 #ifndef ASSERT
   170 #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
   171   _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO)
   173 #else
   175 // This adds an assertion that it is only called from thread_in_native
   176 // The call overhead is skipped for performance in product mode
   177 #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \
   178   _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO )
   180 #endif
   182 // Don't attend to UseVMInterruptibleIO. Always allow interruption.
   183 // Also assumes that it is called from the _thread_blocked state.
   184 // Used by os_sleep().
   186 #define INTERRUPTIBLE_NORESTART_VM_ALWAYS(_cmd, _result, _thread, _clear) \
   187   _INTERRUPTIBLE(os::Solaris::setup_interruptible_already_blocked(_thread), _result = _cmd, _result, _thread, _clear, , , true )
   189 #define INTERRUPTIBLE_RETURN_INT(_cmd, _clear) do { \
   190   int _result; \
   191   do { \
   192     INTERRUPTIBLE(_cmd, _result, _clear); \
   193   } while((_result == OS_ERR) && (errno == EINTR)); \
   194   return _result; \
   195 } while(false)
   197 #define INTERRUPTIBLE_RETURN_INT_VM(_cmd, _clear) do { \
   198   int _result; \
   199   do { \
   200     INTERRUPTIBLE_VM(_cmd, _result, _clear); \
   201   } while((_result == OS_ERR) && (errno == EINTR)); \
   202   return _result; \
   203 } while(false)
   205 #define INTERRUPTIBLE_RETURN_INT_NORESTART(_cmd, _clear) do { \
   206   int _result; \
   207   INTERRUPTIBLE_NORESTART(_cmd, _result, _clear); \
   208   return _result; \
   209 } while(false)
   211 /* Use the RESTARTABLE macros when interruptible io is not needed */
   213 #define RESTARTABLE(_cmd, _result) do { \
   214   do { \
   215     _result = _cmd; \
   216   } while((_result == OS_ERR) && (errno == EINTR)); \
   217 } while(false)
   219 #define RESTARTABLE_RETURN_INT(_cmd) do { \
   220   int _result; \
   221   RESTARTABLE(_cmd, _result); \
   222   return _result; \
   223 } while(false)
   225 inline bool os::numa_has_static_binding()   { return false; }
   226 inline bool os::numa_has_group_homing()     { return true;  }
   228 inline int    os::socket(int domain, int type, int protocol) {
   229   return ::socket(domain, type, protocol);
   230 }
   232 inline int    os::listen(int fd, int count) {
   233   if (fd < 0) return OS_ERR;
   235   return ::listen(fd, count);
   236 }
   238 inline int os::socket_shutdown(int fd, int howto){
   239   return ::shutdown(fd, howto);
   240 }
   242 inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){
   243   return ::getsockname(fd, him, len);
   244 }
   246 inline int os::get_host_name(char* name, int namelen){
   247   return ::gethostname(name, namelen);
   248 }
   250 inline struct hostent* os::get_host_by_name(char* name) {
   251   return ::gethostbyname(name);
   252 }
   254 inline int os::get_sock_opt(int fd, int level, int optname,
   255                             char* optval, socklen_t* optlen) {
   256   return ::getsockopt(fd, level, optname, optval, optlen);
   257 }
   259 inline int os::set_sock_opt(int fd, int level, int optname,
   260                             const char *optval, socklen_t optlen) {
   261   return ::setsockopt(fd, level, optname, optval, optlen);
   262 }
   263 #endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP

mercurial