0N/A/*
4907N/A* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A*
0N/A* This code is free software; you can redistribute it and/or modify it
0N/A* under the terms of the GNU General Public License version 2 only, as
2362N/A* published by the Free Software Foundation.
0N/A*
2362N/A* This code is distributed in the hope that it will be useful, but WITHOUT
0N/A* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A* version 2 for more details (a copy is included in the LICENSE file that
0N/A* accompanied this code).
0N/A*
0N/A* You should have received a copy of the GNU General Public License version
0N/A* 2 along with this work; if not, write to the Free Software Foundation,
0N/A* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A*
0N/A* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
0N/A* or visit www.oracle.com if you need additional information or have any
2362N/A* questions.
2362N/A*
2362N/A*/
0N/A
0N/A#include "prims/jvm.h"
0N/A#include "runtime/frame.inline.hpp"
0N/A#include "runtime/os.hpp"
0N/A#include "utilities/vmError.hpp"
0N/A
0N/A#include <unistd.h>
0N/A#include <sys/resource.h>
0N/A#include <sys/utsname.h>
0N/A
0N/A
0N/A// Check core dump limit and report possible place where core can be found
0N/Avoid os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
0N/A int n;
0N/A struct rlimit rlim;
0N/A bool success;
0N/A
914N/A n = get_core_path(buffer, bufferSize);
0N/A
0N/A if (getrlimit(RLIMIT_CORE, &rlim) != 0) {
0N/A jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id());
0N/A success = true;
914N/A } else {
914N/A switch(rlim.rlim_cur) {
914N/A case RLIM_INFINITY:
914N/A jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id());
914N/A success = true;
914N/A break;
914N/A case 0:
914N/A jio_snprintf(buffer, bufferSize, "Core dumps have been disabled. To enable core dumping, try \"ulimit -c unlimited\" before starting Java again");
914N/A success = false;
914N/A break;
914N/A default:
914N/A jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", current_process_id(), (unsigned long)(rlim.rlim_cur >> 10));
914N/A success = true;
914N/A break;
914N/A }
914N/A }
914N/A VMError::report_coredump_status(buffer, success);
914N/A}
914N/A
914N/Aaddress os::get_caller_pc(int n) {
914N/A#ifdef _NMT_NOINLINE_
914N/A n ++;
914N/A#endif
0N/A frame fr = os::current_frame();
0N/A while (n > 0 && fr.pc() &&
0N/A !os::is_first_C_frame(&fr) && fr.sender_pc()) {
914N/A fr = os::get_sender_for_C_frame(&fr);
914N/A n --;
914N/A }
914N/A if (n == 0) {
0N/A return fr.pc();
0N/A } else {
0N/A return NULL;
0N/A }
0N/A}
0N/A
914N/Aint os::get_last_error() {
914N/A return errno;
914N/A}
914N/A
0N/Abool os::is_debugger_attached() {
0N/A // not implemented
0N/A return false;
914N/A}
914N/A
914N/Avoid os::wait_for_keypress_at_exit(void) {
914N/A // don't do anything on posix platforms
914N/A return;
914N/A}
914N/A
914N/A// Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
914N/A// so on posix, unmap the section at the start and at the end of the chunk that we mapped
3218N/A// rather than unmapping and remapping the whole chunk to get requested alignment.
3218N/Achar* os::reserve_memory_aligned(size_t size, size_t alignment) {
914N/A assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
914N/A "Alignment must be a multiple of allocation granularity (page size)");
914N/A assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
914N/A
914N/A size_t extra_size = size + alignment;
914N/A assert(extra_size >= size, "overflow, size is too large to allow alignment");
3218N/A
3218N/A char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
914N/A
914N/A if (extra_base == NULL) {
914N/A return NULL;
914N/A }
3688N/A
914N/A // Do manual alignment
0N/A char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
0N/A
4637N/A // [ | | ]
4637N/A // ^ extra_base
4637N/A // ^ extra_base + begin_offset == aligned_base
4637N/A // extra_base + begin_offset + size ^
4637N/A // extra_base + extra_size ^
4637N/A // |<>| == begin_offset
4637N/A // end_offset == |<>|
0N/A size_t begin_offset = aligned_base - extra_base;
914N/A size_t end_offset = (extra_base + extra_size) - (aligned_base + size);
914N/A
914N/A if (begin_offset > 0) {
914N/A os::release_memory(extra_base, begin_offset);
914N/A }
914N/A
914N/A if (end_offset > 0) {
914N/A os::release_memory(extra_base + begin_offset + size, end_offset);
914N/A }
914N/A
914N/A return aligned_base;
914N/A}
914N/A
942N/Abool os::can_release_partial_region() {
398N/A return true;
914N/A}
914N/A
914N/Avoid os::Posix::print_load_average(outputStream* st) {
914N/A st->print("load average:");
914N/A double loadavg[3];
914N/A os::loadavg(loadavg, 3);
914N/A st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
430N/A st->cr();
0N/A}
0N/A
0N/Avoid os::Posix::print_rlimit_info(outputStream* st) {
0N/A st->print("rlimit:");
0N/A struct rlimit rlim;
0N/A
0N/A st->print(" STACK ");
0N/A getrlimit(RLIMIT_STACK, &rlim);
0N/A if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
0N/A else st->print("%uk", rlim.rlim_cur >> 10);
0N/A
0N/A st->print(", CORE ");
0N/A getrlimit(RLIMIT_CORE, &rlim);
535N/A if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
117N/A else st->print("%uk", rlim.rlim_cur >> 10);
0N/A
0N/A //Isn't there on solaris
0N/A#ifndef TARGET_OS_FAMILY_solaris
0N/A st->print(", NPROC ");
0N/A getrlimit(RLIMIT_NPROC, &rlim);
0N/A if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
0N/A else st->print("%d", rlim.rlim_cur);
0N/A#endif
0N/A
0N/A st->print(", NOFILE ");
0N/A getrlimit(RLIMIT_NOFILE, &rlim);
0N/A if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
0N/A else st->print("%d", rlim.rlim_cur);
0N/A
0N/A st->print(", AS ");
0N/A getrlimit(RLIMIT_AS, &rlim);
0N/A if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
0N/A else st->print("%uk", rlim.rlim_cur >> 10);
0N/A st->cr();
0N/A}
0N/A
0N/Avoid os::Posix::print_uname_info(outputStream* st) {
0N/A // kernel
0N/A st->print("uname:");
0N/A struct utsname name;
0N/A uname(&name);
0N/A st->print(name.sysname); st->print(" ");
0N/A st->print(name.release); st->print(" ");
0N/A st->print(name.version); st->print(" ");
0N/A st->print(name.machine);
0N/A st->cr();
0N/A}
0N/A
0N/A
0N/A