duke@435: /* hseigel@4465: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. duke@435: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@435: * duke@435: * This code is free software; you can redistribute it and/or modify it duke@435: * under the terms of the GNU General Public License version 2 only, as duke@435: * published by the Free Software Foundation. duke@435: * duke@435: * This code is distributed in the hope that it will be useful, but WITHOUT duke@435: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@435: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@435: * version 2 for more details (a copy is included in the LICENSE file that duke@435: * accompanied this code). duke@435: * duke@435: * You should have received a copy of the GNU General Public License version duke@435: * 2 along with this work; if not, write to the Free Software Foundation, duke@435: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@435: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. duke@435: * duke@435: */ duke@435: stefank@2314: #ifndef OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP stefank@2314: #define OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP stefank@2314: twisti@4318: #include "runtime/atomic.inline.hpp" stefank@2314: #include "runtime/os.hpp" twisti@4318: stefank@2314: #ifdef TARGET_OS_ARCH_solaris_x86 stefank@2314: # include "orderAccess_solaris_x86.inline.hpp" stefank@2314: #endif stefank@2314: #ifdef TARGET_OS_ARCH_solaris_sparc stefank@2314: # include "orderAccess_solaris_sparc.inline.hpp" stefank@2314: #endif stefank@2314: ikrylov@2322: // System includes ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: #include ikrylov@2322: duke@435: inline const char* os::file_separator() { return "/"; } duke@435: inline const char* os::line_separator() { return "\n"; } duke@435: inline const char* os::path_separator() { return ":"; } duke@435: duke@435: // File names are case-sensitive on windows only duke@435: inline int os::file_name_strcmp(const char* s1, const char* s2) { duke@435: return strcmp(s1, s2); duke@435: } duke@435: duke@435: inline bool os::uses_stack_guard_pages() { duke@435: return true; duke@435: } duke@435: duke@435: inline bool os::allocate_stack_guard_pages() { duke@435: assert(uses_stack_guard_pages(), "sanity check"); duke@435: int r = thr_main() ; duke@435: guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; duke@435: return r; duke@435: } duke@435: duke@435: duke@435: // On Solaris, reservations are made on a page by page basis, nothing to do. zgu@3900: inline void os::pd_split_reserved_memory(char *base, size_t size, duke@435: size_t split, bool realloc) { duke@435: } duke@435: duke@435: duke@435: // Bang the shadow pages if they need to be touched to be mapped. duke@435: inline void os::bang_stack_shadow_pages() { duke@435: } ikrylov@2322: inline void os::dll_unload(void *lib) { ::dlclose(lib); } duke@435: ikrylov@2322: inline DIR* os::opendir(const char* dirname) { duke@435: assert(dirname != NULL, "just checking"); duke@435: return ::opendir(dirname); duke@435: } duke@435: ikrylov@2322: inline int os::readdir_buf_size(const char *path) { duke@435: int size = pathconf(path, _PC_NAME_MAX); duke@435: return (size < 0 ? MAXPATHLEN : size) + sizeof(dirent) + 1; duke@435: } duke@435: ikrylov@2322: inline struct dirent* os::readdir(DIR* dirp, dirent* dbuf) { duke@435: assert(dirp != NULL, "just checking"); tamao@5309: #if defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 duke@435: dirent* p; duke@435: int status; duke@435: duke@435: if((status = ::readdir_r(dirp, dbuf, &p)) != 0) { duke@435: errno = status; duke@435: return NULL; duke@435: } else duke@435: return p; tamao@5309: #else // defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 duke@435: return ::readdir_r(dirp, dbuf); tamao@5309: #endif // defined(_LP64) || defined(_GNU_SOURCE) || _FILE_OFFSET_BITS==64 duke@435: } duke@435: ikrylov@2322: inline int os::closedir(DIR *dirp) { ikrylov@2322: assert(dirp != NULL, "argument is NULL"); duke@435: return ::closedir(dirp); duke@435: } duke@435: duke@435: ////////////////////////////////////////////////////////////////////////////// duke@435: //////////////////////////////////////////////////////////////////////////////// duke@435: duke@435: // macros for interruptible io and system calls and system call restarting duke@435: duke@435: #define _INTERRUPTIBLE(_setup, _cmd, _result, _thread, _clear, _before, _after, _int_enable) \ duke@435: do { \ duke@435: _setup; \ duke@435: _before; \ duke@435: OSThread* _osthread = _thread->osthread(); \ duke@435: if (_int_enable && _thread->has_last_Java_frame()) { \ duke@435: /* this is java interruptible io stuff */ \ duke@435: if (os::is_interrupted(_thread, _clear)) { \ duke@435: os::Solaris::bump_interrupted_before_count(); \ duke@435: _result = OS_INTRPT; \ duke@435: } else { \ duke@435: /* _cmd always expands to an assignment to _result */ \ duke@435: if ((_cmd) < 0 && errno == EINTR \ duke@435: && os::is_interrupted(_thread, _clear)) { \ duke@435: os::Solaris::bump_interrupted_during_count(); \ duke@435: _result = OS_INTRPT; \ duke@435: } \ duke@435: } \ duke@435: } else { \ duke@435: /* this is normal blocking io stuff */ \ duke@435: _cmd; \ duke@435: } \ duke@435: _after; \ duke@435: } while(false) duke@435: duke@435: // Interruptible io support + restarting of interrupted system calls duke@435: duke@435: #ifndef ASSERT duke@435: duke@435: #define INTERRUPTIBLE(_cmd, _result, _clear) do { \ duke@435: _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO); \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)) duke@435: duke@435: #else duke@435: duke@435: // This adds an assertion that it is only called from thread_in_native duke@435: // The call overhead is skipped for performance in product mode duke@435: #define INTERRUPTIBLE(_cmd, _result, _clear) do { \ duke@435: _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO ); \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)) duke@435: duke@435: #endif duke@435: duke@435: // Used for calls from _thread_in_vm, not from _thread_in_native duke@435: #define INTERRUPTIBLE_VM(_cmd, _result, _clear) do { \ duke@435: _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible(_thread), UseVMInterruptibleIO ); \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)) duke@435: duke@435: /* Use NORESTART when the system call cannot return EINTR, when something other duke@435: than a system call is being invoked, or when the caller must do EINTR duke@435: handling. */ duke@435: duke@435: #ifndef ASSERT duke@435: duke@435: #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \ duke@435: _INTERRUPTIBLE( JavaThread* _thread = (JavaThread*)ThreadLocalStorage::thread(),_result = _cmd, _result, _thread, _clear, , , UseVMInterruptibleIO) duke@435: duke@435: #else duke@435: duke@435: // This adds an assertion that it is only called from thread_in_native duke@435: // The call overhead is skipped for performance in product mode duke@435: #define INTERRUPTIBLE_NORESTART(_cmd, _result, _clear) \ duke@435: _INTERRUPTIBLE(JavaThread* _thread = os::Solaris::setup_interruptible_native(), _result = _cmd, _result, _thread, _clear, , os::Solaris::cleanup_interruptible_native(_thread), UseVMInterruptibleIO ) duke@435: duke@435: #endif duke@435: duke@435: // Don't attend to UseVMInterruptibleIO. Always allow interruption. duke@435: // Also assumes that it is called from the _thread_blocked state. duke@435: // Used by os_sleep(). duke@435: duke@435: #define INTERRUPTIBLE_NORESTART_VM_ALWAYS(_cmd, _result, _thread, _clear) \ duke@435: _INTERRUPTIBLE(os::Solaris::setup_interruptible_already_blocked(_thread), _result = _cmd, _result, _thread, _clear, , , true ) duke@435: duke@435: #define INTERRUPTIBLE_RETURN_INT(_cmd, _clear) do { \ duke@435: int _result; \ duke@435: do { \ duke@435: INTERRUPTIBLE(_cmd, _result, _clear); \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)); \ duke@435: return _result; \ duke@435: } while(false) duke@435: duke@435: #define INTERRUPTIBLE_RETURN_INT_VM(_cmd, _clear) do { \ duke@435: int _result; \ duke@435: do { \ duke@435: INTERRUPTIBLE_VM(_cmd, _result, _clear); \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)); \ duke@435: return _result; \ duke@435: } while(false) duke@435: duke@435: #define INTERRUPTIBLE_RETURN_INT_NORESTART(_cmd, _clear) do { \ duke@435: int _result; \ duke@435: INTERRUPTIBLE_NORESTART(_cmd, _result, _clear); \ duke@435: return _result; \ duke@435: } while(false) duke@435: duke@435: /* Use the RESTARTABLE macros when interruptible io is not needed */ duke@435: duke@435: #define RESTARTABLE(_cmd, _result) do { \ duke@435: do { \ duke@435: _result = _cmd; \ duke@435: } while((_result == OS_ERR) && (errno == EINTR)); \ duke@435: } while(false) duke@435: duke@435: #define RESTARTABLE_RETURN_INT(_cmd) do { \ duke@435: int _result; \ duke@435: RESTARTABLE(_cmd, _result); \ duke@435: return _result; \ duke@435: } while(false) iveresov@576: iveresov@576: inline bool os::numa_has_static_binding() { return false; } iveresov@576: inline bool os::numa_has_group_homing() { return true; } stefank@2314: ikrylov@2322: inline int os::socket(int domain, int type, int protocol) { ikrylov@2322: return ::socket(domain, type, protocol); ikrylov@2322: } ikrylov@2322: ikrylov@2322: inline int os::listen(int fd, int count) { ikrylov@2322: if (fd < 0) return OS_ERR; ikrylov@2322: ikrylov@2322: return ::listen(fd, count); ikrylov@2322: } ikrylov@2322: ikrylov@2322: inline int os::socket_shutdown(int fd, int howto){ ikrylov@2322: return ::shutdown(fd, howto); ikrylov@2322: } ikrylov@2322: phh@3344: inline int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len){ phh@3344: return ::getsockname(fd, him, len); ikrylov@2322: } ikrylov@2322: ikrylov@2322: inline int os::get_host_name(char* name, int namelen){ ikrylov@2322: return ::gethostname(name, namelen); ikrylov@2322: } ikrylov@2322: phh@3344: inline struct hostent* os::get_host_by_name(char* name) { ikrylov@2322: return ::gethostbyname(name); ikrylov@2322: } phh@3344: ikrylov@2322: inline int os::get_sock_opt(int fd, int level, int optname, phh@3344: char* optval, socklen_t* optlen) { phh@3344: return ::getsockopt(fd, level, optname, optval, optlen); ikrylov@2322: } ikrylov@2322: ikrylov@2322: inline int os::set_sock_opt(int fd, int level, int optname, phh@3344: const char *optval, socklen_t optlen) { ikrylov@2322: return ::setsockopt(fd, level, optname, optval, optlen); ikrylov@2322: } stefank@2314: #endif // OS_SOLARIS_VM_OS_SOLARIS_INLINE_HPP