annotate src/os/posix/vm/os_posix.cpp @ 4709:63085fd28f10

Merge
author jcoomes
date Fri, 19 Jul 2013 17:18:49 -0700
parents f2a9de120e2d 73863f836e34
children 97c998b91726
rev   line source
ctornqvi@2085 1 /*
ctornqvi@2085 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
ctornqvi@2085 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ctornqvi@2085 4 *
ctornqvi@2085 5 * This code is free software; you can redistribute it and/or modify it
ctornqvi@2085 6 * under the terms of the GNU General Public License version 2 only, as
ctornqvi@2085 7 * published by the Free Software Foundation.
ctornqvi@2085 8 *
ctornqvi@2085 9 * This code is distributed in the hope that it will be useful, but WITHOUT
ctornqvi@2085 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ctornqvi@2085 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ctornqvi@2085 12 * version 2 for more details (a copy is included in the LICENSE file that
ctornqvi@2085 13 * accompanied this code).
ctornqvi@2085 14 *
ctornqvi@2085 15 * You should have received a copy of the GNU General Public License version
ctornqvi@2085 16 * 2 along with this work; if not, write to the Free Software Foundation,
ctornqvi@2085 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ctornqvi@2085 18 *
ctornqvi@2085 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ctornqvi@2085 20 * or visit www.oracle.com if you need additional information or have any
ctornqvi@2085 21 * questions.
ctornqvi@2085 22 *
ctornqvi@2085 23 */
ctornqvi@2085 24
ctornqvi@2085 25 #include "prims/jvm.h"
zgu@3863 26 #include "runtime/frame.inline.hpp"
ctornqvi@2085 27 #include "runtime/os.hpp"
ctornqvi@2085 28 #include "utilities/vmError.hpp"
ctornqvi@2085 29
ctornqvi@2085 30 #include <unistd.h>
ctornqvi@2085 31 #include <sys/resource.h>
nloodin@3380 32 #include <sys/utsname.h>
nloodin@3380 33
ctornqvi@2085 34
ctornqvi@2085 35 // Check core dump limit and report possible place where core can be found
ctornqvi@2085 36 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
mikael@3866 37 int n;
ctornqvi@2085 38 struct rlimit rlim;
ctornqvi@2085 39 bool success;
ctornqvi@2085 40
mikael@3866 41 n = get_core_path(buffer, bufferSize);
ctornqvi@2085 42
ctornqvi@2085 43 if (getrlimit(RLIMIT_CORE, &rlim) != 0) {
mikael@3866 44 jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id());
ctornqvi@2085 45 success = true;
ctornqvi@2085 46 } else {
ctornqvi@2085 47 switch(rlim.rlim_cur) {
ctornqvi@2085 48 case RLIM_INFINITY:
mikael@3866 49 jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id());
ctornqvi@2085 50 success = true;
ctornqvi@2085 51 break;
ctornqvi@2085 52 case 0:
ctornqvi@2085 53 jio_snprintf(buffer, bufferSize, "Core dumps have been disabled. To enable core dumping, try \"ulimit -c unlimited\" before starting Java again");
ctornqvi@2085 54 success = false;
ctornqvi@2085 55 break;
ctornqvi@2085 56 default:
mikael@3866 57 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));
ctornqvi@2085 58 success = true;
ctornqvi@2085 59 break;
ctornqvi@2085 60 }
ctornqvi@2085 61 }
ctornqvi@2085 62 VMError::report_coredump_status(buffer, success);
ctornqvi@2085 63 }
ctornqvi@2085 64
zgu@3863 65 address os::get_caller_pc(int n) {
zgu@3863 66 #ifdef _NMT_NOINLINE_
zgu@3863 67 n ++;
zgu@3863 68 #endif
zgu@3863 69 frame fr = os::current_frame();
zgu@3863 70 while (n > 0 && fr.pc() &&
zgu@3863 71 !os::is_first_C_frame(&fr) && fr.sender_pc()) {
zgu@3863 72 fr = os::get_sender_for_C_frame(&fr);
zgu@3863 73 n --;
zgu@3863 74 }
zgu@3863 75 if (n == 0) {
zgu@3863 76 return fr.pc();
zgu@3863 77 } else {
zgu@3863 78 return NULL;
zgu@3863 79 }
zgu@3863 80 }
zgu@3863 81
phh@3030 82 int os::get_last_error() {
phh@3030 83 return errno;
phh@3030 84 }
phh@3030 85
sla@2149 86 bool os::is_debugger_attached() {
sla@2149 87 // not implemented
sla@2149 88 return false;
sla@2149 89 }
sla@2149 90
sla@2149 91 void os::wait_for_keypress_at_exit(void) {
sla@2149 92 // don't do anything on posix platforms
sla@2149 93 return;
sla@2149 94 }
nloodin@3380 95
brutisso@4373 96 // Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
brutisso@4373 97 // so on posix, unmap the section at the start and at the end of the chunk that we mapped
brutisso@4373 98 // rather than unmapping and remapping the whole chunk to get requested alignment.
brutisso@4373 99 char* os::reserve_memory_aligned(size_t size, size_t alignment) {
brutisso@4373 100 assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
brutisso@4373 101 "Alignment must be a multiple of allocation granularity (page size)");
brutisso@4373 102 assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
brutisso@4373 103
brutisso@4373 104 size_t extra_size = size + alignment;
brutisso@4373 105 assert(extra_size >= size, "overflow, size is too large to allow alignment");
brutisso@4373 106
brutisso@4373 107 char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
brutisso@4373 108
brutisso@4373 109 if (extra_base == NULL) {
brutisso@4373 110 return NULL;
brutisso@4373 111 }
brutisso@4373 112
brutisso@4373 113 // Do manual alignment
brutisso@4373 114 char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
brutisso@4373 115
brutisso@4373 116 // [ | | ]
brutisso@4373 117 // ^ extra_base
brutisso@4373 118 // ^ extra_base + begin_offset == aligned_base
brutisso@4373 119 // extra_base + begin_offset + size ^
brutisso@4373 120 // extra_base + extra_size ^
brutisso@4373 121 // |<>| == begin_offset
brutisso@4373 122 // end_offset == |<>|
brutisso@4373 123 size_t begin_offset = aligned_base - extra_base;
brutisso@4373 124 size_t end_offset = (extra_base + extra_size) - (aligned_base + size);
brutisso@4373 125
brutisso@4373 126 if (begin_offset > 0) {
brutisso@4373 127 os::release_memory(extra_base, begin_offset);
brutisso@4373 128 }
brutisso@4373 129
brutisso@4373 130 if (end_offset > 0) {
brutisso@4373 131 os::release_memory(extra_base + begin_offset + size, end_offset);
brutisso@4373 132 }
brutisso@4373 133
brutisso@4373 134 return aligned_base;
brutisso@4373 135 }
brutisso@4373 136
jcoomes@4703 137 bool os::can_release_partial_region() {
jcoomes@4703 138 return true;
jcoomes@4703 139 }
jcoomes@4703 140
nloodin@3380 141 void os::Posix::print_load_average(outputStream* st) {
nloodin@3380 142 st->print("load average:");
nloodin@3380 143 double loadavg[3];
nloodin@3380 144 os::loadavg(loadavg, 3);
nloodin@3380 145 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
nloodin@3380 146 st->cr();
nloodin@3380 147 }
nloodin@3380 148
nloodin@3380 149 void os::Posix::print_rlimit_info(outputStream* st) {
nloodin@3380 150 st->print("rlimit:");
nloodin@3380 151 struct rlimit rlim;
nloodin@3380 152
nloodin@3380 153 st->print(" STACK ");
nloodin@3380 154 getrlimit(RLIMIT_STACK, &rlim);
nloodin@3380 155 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
nloodin@3380 156 else st->print("%uk", rlim.rlim_cur >> 10);
nloodin@3380 157
nloodin@3380 158 st->print(", CORE ");
nloodin@3380 159 getrlimit(RLIMIT_CORE, &rlim);
nloodin@3380 160 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
nloodin@3380 161 else st->print("%uk", rlim.rlim_cur >> 10);
nloodin@3380 162
nloodin@3380 163 //Isn't there on solaris
nloodin@3380 164 #ifndef TARGET_OS_FAMILY_solaris
nloodin@3380 165 st->print(", NPROC ");
nloodin@3380 166 getrlimit(RLIMIT_NPROC, &rlim);
nloodin@3380 167 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
nloodin@3380 168 else st->print("%d", rlim.rlim_cur);
nloodin@3380 169 #endif
nloodin@3380 170
nloodin@3380 171 st->print(", NOFILE ");
nloodin@3380 172 getrlimit(RLIMIT_NOFILE, &rlim);
nloodin@3380 173 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
nloodin@3380 174 else st->print("%d", rlim.rlim_cur);
nloodin@3380 175
nloodin@3380 176 st->print(", AS ");
nloodin@3380 177 getrlimit(RLIMIT_AS, &rlim);
nloodin@3380 178 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
nloodin@3380 179 else st->print("%uk", rlim.rlim_cur >> 10);
nloodin@3380 180 st->cr();
nloodin@3380 181 }
nloodin@3380 182
nloodin@3380 183 void os::Posix::print_uname_info(outputStream* st) {
nloodin@3380 184 // kernel
nloodin@3380 185 st->print("uname:");
nloodin@3380 186 struct utsname name;
nloodin@3380 187 uname(&name);
nloodin@3380 188 st->print(name.sysname); st->print(" ");
nloodin@3380 189 st->print(name.release); st->print(" ");
nloodin@3380 190 st->print(name.version); st->print(" ");
nloodin@3380 191 st->print(name.machine);
nloodin@3380 192 st->cr();
nloodin@3380 193 }
nloodin@3380 194
nloodin@3380 195