hotspot/src/os/linux/vm/os_linux.cpp
author tschatzl
Wed, 11 Sep 2013 16:25:02 +0200
changeset 19986 33d188c66ed9
parent 19732 88f375dd7d65
child 20005 6fb8070af25d
permissions -rw-r--r--
8010722: assert: failed: heap size is too big for compressed oops Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation. Reviewed-by: stefank, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
     2
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    25
// no precompiled headers
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    26
#include "classfile/classLoader.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    27
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    28
#include "classfile/vmSymbols.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    29
#include "code/icBuffer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    30
#include "code/vtableStubs.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    31
#include "compiler/compileBroker.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14471
diff changeset
    32
#include "compiler/disassembler.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    33
#include "interpreter/interpreter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    34
#include "jvm_linux.h"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    35
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    36
#include "memory/filemap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    37
#include "mutex_linux.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    38
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    39
#include "os_share_linux.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    40
#include "prims/jniFastGetField.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    41
#include "prims/jvm.h"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    42
#include "prims/jvm_misc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    43
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    44
#include "runtime/extendedPC.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    45
#include "runtime/globals.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    46
#include "runtime/interfaceSupport.hpp"
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
    47
#include "runtime/init.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    48
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    49
#include "runtime/javaCalls.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    50
#include "runtime/mutexLocker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    51
#include "runtime/objectMonitor.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    52
#include "runtime/osThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    53
#include "runtime/perfMemory.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    54
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    55
#include "runtime/statSampler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    56
#include "runtime/stubRoutines.hpp"
14583
d70ee55535f4 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 14471
diff changeset
    57
#include "runtime/thread.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    58
#include "runtime/threadCritical.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    59
#include "runtime/timer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    60
#include "services/attachListener.hpp"
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
    61
#include "services/memTracker.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    62
#include "services/runtimeService.hpp"
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
    63
#include "utilities/decoder.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    64
#include "utilities/defaultStream.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    65
#include "utilities/events.hpp"
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
    66
#include "utilities/elfFile.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    67
#include "utilities/growableArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    68
#include "utilities/vmError.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// put OS-includes here
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
# include <sys/types.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
# include <sys/mman.h>
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
    73
# include <sys/stat.h>
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
    74
# include <sys/select.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
# include <pthread.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
# include <signal.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
# include <errno.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
# include <dlfcn.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
# include <stdio.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
# include <unistd.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
# include <sys/resource.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
# include <pthread.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
# include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
# include <sys/time.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
# include <sys/times.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
# include <sys/utsname.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
# include <sys/socket.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
# include <sys/wait.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
# include <pwd.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
# include <poll.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
# include <semaphore.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
# include <fcntl.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
# include <string.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
# include <syscall.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
# include <sys/sysinfo.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
# include <gnu/libc-version.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
# include <sys/ipc.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
# include <sys/shm.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
# include <link.h>
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
   100
# include <stdint.h>
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
   101
# include <inttypes.h>
7458
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
   102
# include <sys/ioctl.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   104
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   105
// getrusage() is prepared to handle the associated failure.
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   106
#ifndef RUSAGE_THREAD
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   107
#define RUSAGE_THREAD   (1)               /* only the calling thread */
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   108
#endif
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   109
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
#define MAX_PATH    (2 * K)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
// for timer info max values which include all bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
   115
#define LARGEPAGES_BIT (1 << 6)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// global variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
julong os::Linux::_physical_memory = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
address   os::Linux::_initial_thread_stack_bottom = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
uintptr_t os::Linux::_initial_thread_stack_size   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
Mutex* os::Linux::_createThread_lock = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
pthread_t os::Linux::_main_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
int os::Linux::_page_size = -1;
17090
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
   128
const int os::Linux::_vm_default_page_size = (8 * K);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
bool os::Linux::_is_floating_stack = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
bool os::Linux::_is_NPTL = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
bool os::Linux::_supports_fast_thread_cpu_time = false;
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   132
const char * os::Linux::_glibc_version = NULL;
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   133
const char * os::Linux::_libpthread_version = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
static jlong initial_time_count=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
static int clock_tics_per_sec = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
// For diagnostics to print a message once. see run_periodic_checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
static sigset_t check_signal_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
static bool check_signals = true;;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
static pid_t _initial_pid = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
/* Signal number used to suspend/resume a thread */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
/* do not use any signal number less than SIGSEGV, see 4355769 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
static int SR_signum = SIGUSR2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
sigset_t SR_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   151
/* Used to protect dlsym() calls */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   152
static pthread_mutex_t dl_mutex;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   153
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   154
// Declarations
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   155
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   156
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   157
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   158
class MemNotifyThread: public Thread {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   159
  friend class VMStructs;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   160
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   161
  virtual void run();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   162
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   163
 private:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   164
  static MemNotifyThread* _memnotify_thread;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   165
  int _fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   166
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   167
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   168
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   169
  // Constructor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   170
  MemNotifyThread(int fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   171
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   172
  // Tester
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   173
  bool is_memnotify_thread() const { return true; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   174
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   175
  // Printing
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   176
  char* name() const { return (char*)"Linux MemNotify Thread"; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   177
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   178
  // Returns the single instance of the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   179
  static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   180
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   181
  // Create and start the single instance of MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   182
  static void start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   183
};
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   184
#endif // JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   185
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
// utility functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
static int SR_initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
julong os::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  return Linux::available_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
julong os::Linux::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  return (julong)si.freeram * si.mem_unit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
julong os::physical_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  return Linux::physical_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
// environment support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
bool os::getenv(const char* name, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  const char* val = ::getenv(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  if (val != NULL && strlen(val) < (size_t)len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    strcpy(buf, val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  if (len > 0) buf[0] = 0;  // return a null string
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
// Return true if user is running as root.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
bool os::have_special_privileges() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  static bool privileges = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  if (!init) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    privileges = (getuid() != geteuid()) || (getgid() != getegid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  return privileges;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
#ifndef SYS_gettid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
// i386: 224, ia64: 1105, amd64: 186, sparc 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
#ifdef __ia64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
#define SYS_gettid 1105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
#elif __i386__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
#define SYS_gettid 224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
#elif __amd64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
#define SYS_gettid 186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
#elif __sparc__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
#define SYS_gettid 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
#error define gettid for the arch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
// Cpu architecture string
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   249
#if   defined(ZERO)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   250
static char cpu_arch[] = ZERO_LIBARCH;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   251
#elif defined(IA64)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
static char cpu_arch[] = "ia64";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
#elif defined(IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
static char cpu_arch[] = "i386";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
#elif defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
static char cpu_arch[] = "amd64";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   257
#elif defined(ARM)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   258
static char cpu_arch[] = "arm";
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   259
#elif defined(PPC)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   260
static char cpu_arch[] = "ppc";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
#elif defined(SPARC)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
#  ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
static char cpu_arch[] = "sparcv9";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
#  else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
static char cpu_arch[] = "sparc";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
#  endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
#error Add appropriate cpu_arch setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
// pid_t gettid()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
// Returns the kernel thread id of the currently running thread. Kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
// thread id is used to access /proc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
// (Note that getpid() on LinuxThreads returns kernel thread id too; but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
// on NPTL, it returns the same pid for all threads, as required by POSIX.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
pid_t os::Linux::gettid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  int rslt = syscall(SYS_gettid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  if (rslt == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
     // old kernel, no NPTL support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
     return getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
     return (pid_t)rslt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
// Most versions of linux have a bug where the number of processors are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
// determined by looking at the /proc file system.  In a chroot environment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
// the system call returns 1.  This causes the VM to act as if it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
// a single processor and elide locking (see is_MP() call).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
static bool unsafe_chroot_detected = false;
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   295
static const char *unstable_chroot_error = "/proc file system not found.\n"
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   296
                     "Java may be unstable running multithreaded in a chroot "
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   297
                     "environment on Linux when /proc filesystem is not mounted.";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
void os::Linux::initialize_system_info() {
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   300
  set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   301
  if (processor_count() == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    FILE *fp = fopen(fname, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    if (fp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      unsafe_chroot_detected = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   313
  assert(processor_count() > 0, "linux error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
void os::init_system_properties_values() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
//  char arch[12];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
//  sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  // The next steps are taken in the product version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  //
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   322
  // Obtain the JAVA_HOME value from the location of libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  // This library should be located at:
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   324
  // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  // If "/jre/lib/" appears at the right place in the path, then we
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   327
  // assume libjvm.so is installed in a JDK and we use this path.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  // Otherwise exit with message: "Could not create the Java virtual machine."
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  // The following extra steps are taken in the debugging version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // If "/jre/lib/" does NOT appear at the right place in the path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // instead of exit check for $JAVA_HOME environment variable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   337
  // then we append a fake suffix "hotspot/libjvm.so" to this path so
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   338
  // it looks like libjvm.so is installed there
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   339
  // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // Otherwise exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  // Important note: if the location of libjvm.so changes this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  // code needs to be changed accordingly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  // The next few definitions allow the code to be verbatim:
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   347
#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
#define getenv(n) ::getenv(n)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
 * See ld(1):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
 *      The linker uses the following search paths to locate required
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
 *      shared libraries:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
 *        1: ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
 *        ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
 *        7: The default directories, normally /lib and /usr/lib.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
 */
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   358
#if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   359
#define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   360
#else
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
#define DEFAULT_LIBPATH "/lib:/usr/lib"
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   362
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
#define EXTENSIONS_DIR  "/lib/ext"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
#define ENDORSED_DIR    "/lib/endorsed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
#define REG_DIR         "/usr/java/packages"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    /* sysclasspath, java_home, dll_dir */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
        char *home_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        char *dll_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
        char *pslash;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
        char buf[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
        os::jvm_path(buf, sizeof(buf));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
        // Found the full path to libjvm.so.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
        // Now cut the path to <java_home>/jre if we can.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        *(strrchr(buf, '/')) = '\0';  /* get rid of /libjvm.so */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
        if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
            *pslash = '\0';           /* get rid of /{client|server|hotspot} */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
        dll_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
        if (dll_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
        strcpy(dll_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
        Arguments::set_dll_dir(dll_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
        if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
            pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
            if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
                *pslash = '\0';       /* get rid of /<arch> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
                pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
                if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
                    *pslash = '\0';   /* get rid of /lib */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
        home_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
        if (home_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
        strcpy(home_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        Arguments::set_java_home(home_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
        if (!set_boot_path('/', ':'))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
     * Where to look for native libraries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
     * Note: Due to a legacy implementation, most of the library path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
     * is set in the launcher.  This was to accomodate linking restrictions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
     * on legacy Linux implementations (which are no longer supported).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
     * However, to prevent the proliferation of improperly built native
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
     * libraries, the new path component /usr/java/packages is added here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
        char *ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
         * Construct the invariant part of ld_library_path. Note that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
         * space for the colon and the trailing null are provided by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
         * nulls included by the sizeof operator (so actually we allocate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
         * a byte more than necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
        ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
            strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
        sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
         * Get the user setting of LD_LIBRARY_PATH, and prepended it.  It
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
         * should always exist (until the legacy problem cited above is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
         * addressed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
        char *v = getenv("LD_LIBRARY_PATH");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
        if (v != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
            char *t = ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
            /* That's +1 for the colon and +1 for the trailing '\0' */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
            ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
            sprintf(ld_library_path, "%s:%s", v, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
        Arguments::set_library_path(ld_library_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
     * Extensions directories.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
     * Note that the space for the colon and the trailing null are provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
     * by the nulls included by the sizeof operator (so actually one byte more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
     * than necessary is allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        char *buf = malloc(strlen(Arguments::get_java_home()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
            sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
        sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
            Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
        Arguments::set_ext_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    /* Endorsed standards default directory. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        char * buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
        buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
        sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
        Arguments::set_endorsed_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
#undef malloc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
#undef getenv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
#undef EXTENSIONS_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
#undef ENDORSED_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  // Done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
// breakpoint support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
void os::breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  BREAKPOINT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
extern "C" void breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // use debugger to set breakpoint here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
// signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
debug_only(static bool signal_sets_initialized = false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
bool os::Linux::is_sig_ignored(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      struct sigaction oact;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      sigaction(sig, (struct sigaction*)NULL, &oact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*,  oact.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
                                     : CAST_FROM_FN_PTR(void*,  oact.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
      if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
      else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
           return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
void os::Linux::signal_sets_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  // Should also have an assertion stating we are still single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  assert(!signal_sets_initialized, "Already initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  // Fill in signals that are necessarily unblocked for all threads in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // the VM. Currently, we unblock the following signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  //                         by -Xrs (=ReduceSignalUsage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // other threads. The "ReduceSignalUsage" boolean tells us not to alter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // the dispositions or masks wrt these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // Programs embedding the VM that want to use the above signals for their
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // own purposes must, at this time, use the "-Xrs" option to prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // (See bug 4345157, and other related bugs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // In reality, though, unblocking these signals is really a nop, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  // these signals are not blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  sigemptyset(&unblocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  sigemptyset(&allowdebug_blocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  sigaddset(&unblocked_sigs, SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  sigaddset(&unblocked_sigs, SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  sigaddset(&unblocked_sigs, SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  sigaddset(&unblocked_sigs, SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  sigaddset(&unblocked_sigs, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
   if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
      sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
   if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
      sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
   if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
      sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  // Fill in signals that are blocked by all but the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  sigemptyset(&vm_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  if (!ReduceSignalUsage)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
    sigaddset(&vm_sigs, BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  debug_only(signal_sets_initialized = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
// These are signals that are unblocked while a thread is running Java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
// (For some reason, they get blocked by default.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
sigset_t* os::Linux::unblocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  return &unblocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
// These are the signals that are blocked while a (non-VM) thread is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
// running Java. Only the VM thread handles these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
sigset_t* os::Linux::vm_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  return &vm_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
// These are signals that are blocked during cond_wait to allow debugger in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
sigset_t* os::Linux::allowdebug_blocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  return &allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
void os::Linux::hotspot_sigmask(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  //Save caller's signal mask before setting VM signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  sigset_t caller_sigmask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  osthread->set_caller_sigmask(caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    if (thread->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
      // Only the VM thread handles BREAK_SIGNAL ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      // ... all other threads block BREAK_SIGNAL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
// detecting pthread library
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
void os::Linux::libpthread_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  // generic name for earlier versions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Define macros here so we can build HotSpot on old systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
# ifndef _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
# define _CS_GNU_LIBC_VERSION 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
# ifndef _CS_GNU_LIBPTHREAD_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
# define _CS_GNU_LIBPTHREAD_VERSION 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   615
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
     confstr(_CS_GNU_LIBC_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
     os::Linux::set_glibc_version(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
     // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
     static char _gnu_libc_version[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
     jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
              "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
     os::Linux::set_glibc_version(_gnu_libc_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   628
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
     confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
     // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
     // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   632
     // is the case. LinuxThreads has a hard limit on max number of threads.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   633
     // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   634
     // On the other hand, NPTL does not have such a limit, sysconf()
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   635
     // will return -1 and errno is not changed. Check if it is really NPTL.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
     if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   637
         strstr(str, "NPTL") &&
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   638
         sysconf(_SC_THREAD_THREADS_MAX) > 0) {
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   639
       free(str);
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   640
       os::Linux::set_libpthread_version("linuxthreads");
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   641
     } else {
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   642
       os::Linux::set_libpthread_version(str);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  } else {
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   645
    // glibc before 2.3.2 only has LinuxThreads.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   646
    os::Linux::set_libpthread_version("linuxthreads");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  if (strstr(libpthread_version(), "NPTL")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
     os::Linux::set_is_NPTL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
     os::Linux::set_is_LinuxThreads();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  // LinuxThreads have two flavors: floating-stack mode, which allows variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  // stack size; and fixed-stack mode. NPTL is always floating-stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
     os::Linux::set_is_floating_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
// thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// Force Linux kernel to expand current thread stack. If "bottom" is close
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// to the stack guard, caller should block all signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
// MAP_GROWSDOWN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
//   A special mmap() flag that is used to implement thread stacks. It tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
//   kernel that the memory region should extend downwards when needed. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
//   allows early versions of LinuxThreads to only mmap the first few pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
//   when creating a new thread. Linux kernel will automatically expand thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
//   stack as needed (on page faults).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
//   However, because the memory region of a MAP_GROWSDOWN stack can grow on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
//   demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
//   region, it's hard to tell if the fault is due to a legitimate stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
//   access or because of reading/writing non-exist memory (e.g. buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
//   overrun). As a rule, if the fault happens below current stack pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
//   Linux kernel does not expand stack, instead a SIGSEGV is sent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
//   application (see Linux kernel fault.c).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
//   This Linux feature can cause SIGSEGV when VM bangs thread stack for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
//   stack overflow detection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
//   Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
//   not use this flag. However, the stack of initial thread is not created
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
//   by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
//   unlikely) that user code can create a thread with MAP_GROWSDOWN stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
//   and then attach the thread to JVM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
// To get around the problem and allow stack banging on Linux, we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
// manually expand thread stack after receiving the SIGSEGV.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
// There are two ways to expand thread stack to address "bottom", we used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
// both of them in JVM before 1.5:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
//   1. adjust stack pointer first so that it is below "bottom", and then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
//      touch "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
//   2. mmap() the page in question
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
// Now alternate signal stack is gone, it's harder to use 2. For instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
// if current sp is already near the lower end of page 101, and we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
// call mmap() to map page 100, it is possible that part of the mmap() frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
// will be placed in page 100. When page 100 is mapped, it is zero-filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
// That will destroy the mmap() frame and cause VM to crash.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
// The following code works by adjusting sp first, then accessing the "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
// page to force a page fault. Linux kernel will then automatically expand the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
// stack mapping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
// _expand_stack_to() assumes its frame size is less than page size, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
// should always be true if the function is not inlined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
#if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
#define NOINLINE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
#define NOINLINE __attribute__ ((noinline))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
static void _expand_stack_to(address bottom) NOINLINE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
static void _expand_stack_to(address bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  address sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  volatile char *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  // Adjust bottom to point to the largest address within the same page, it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  // gives us a one-page buffer if alloca() allocates slightly more memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  bottom += os::Linux::page_size() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  // sp might be slightly above current stack pointer; if that's the case, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // will alloca() a little more space than necessary, which is OK. Don't use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  // os::current_stack_pointer(), as its result can be slightly below current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  // stack pointer, causing us to not alloca enough to reach "bottom".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  sp = (address)&sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  if (sp > bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    size = sp - bottom;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    p = (volatile char *)alloca(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    p[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  assert(t!=NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  assert(t->osthread()->expanding_stack(), "expand should be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  assert(t->stack_base() != NULL, "stack_base was not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  if (addr <  t->stack_base() && addr >= t->stack_yellow_zone_base()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    sigset_t mask_all, old_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    sigfillset(&mask_all);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    _expand_stack_to(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
// create new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
static address highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
// check if it's safe to start a new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
static bool _thread_safety_check(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    //   Heap is mmap'ed at lower end of memory space. Thread stacks are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    //   allocated (MAP_FIXED) from high address space. Every thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    //   occupies a fixed size slot (usually 2Mbytes, but user can change
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    //   it to other values if they rebuild LinuxThreads).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    // Problem with MAP_FIXED is that mmap() can still succeed even part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    // the memory region has already been mmap'ed. That means if we have too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    // many threads and/or very large heap, eventually thread stack will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    // collide with heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    // Here we try to prevent heap/stack collision by comparing current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    // stack bottom with the highest address that has been mmap'ed by JVM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    // plus a safety margin for memory maps created by native code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
    // This feature can be disabled by setting ThreadSafetyMargin to 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    if (ThreadSafetyMargin > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
      address stack_bottom = os::current_stack_base() - os::current_stack_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
      // not safe if our stack extends below the safety margin
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
      return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    // Floating stack LinuxThreads or NPTL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    //   Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    //   there's not enough space left, pthread_create() will fail. If we come
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
    //   here, that means enough space has been reserved for stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
// Thread start routine for all newly created threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
static void *java_start(Thread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
  // Try to randomize the cache line index of hot stack frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  // This helps when threads of the same stack traces evict each other's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  // cache lines. The threads can be either from the same JVM instance, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  // from different JVM instances. The benefit is especially true for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  // processors with hyperthreading technology.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  static int counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  int pid = os::current_process_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  alloca(((pid ^ counter++) & 7) * 128);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  ThreadLocalStorage::set_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  Monitor* sync = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  // non floating stack LinuxThreads needs extra check, see above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  if (!_thread_safety_check(thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    osthread->set_state(ZOMBIE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  // thread_id is kernel thread id (similar to Solaris LWP id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  // handshaking with parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    osthread->set_state(INITIALIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    // wait until os::start_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
    while (osthread->get_state() == INITIALIZED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
      sync->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  // call one more level start routine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  thread->run();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  assert(thread->osthread() == NULL, "caller responsible");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
  // set the correct thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  osthread->set_thread_type(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  // Initial state is ALLOCATED but not INITIALIZED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  osthread->set_state(ALLOCATED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // init thread attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  pthread_attr_t attr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  pthread_attr_init(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  // stack size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  if (os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
    // calculate stack size if it's not specified by caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
    if (stack_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
      stack_size = os::Linux::default_stack_size(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
      switch (thr_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      case os::java_thread:
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   894
        // Java threads use ThreadStackSize which default value can be
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   895
        // changed with the flag -Xss
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   896
        assert (JavaThread::stack_size_at_create() > 0, "this should be set");
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   897
        stack_size = JavaThread::stack_size_at_create();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
      case os::compiler_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
        if (CompilerThreadStackSize > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
          stack_size = (size_t)(CompilerThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
        } // else fall through:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
          // use VMThreadStackSize if CompilerThreadStackSize is not defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
      case os::vm_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
      case os::pgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      case os::cgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
      case os::watcher_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
        if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
    stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    pthread_attr_setstacksize(&attr, stack_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
    // let pthread_create() pick the default value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  // glibc guard page
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
  pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  ThreadState state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    // Serialize thread creation if we are running with fixed stack LinuxThreads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
    bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
      os::Linux::createThread_lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    pthread_t tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
    pthread_attr_destroy(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    if (ret != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
      if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
        perror("pthread_create()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
      // Need to clean up stuff we've allocated so far
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      if (lock) os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
    // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
    osthread->set_pthread_id(tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
    // Wait until child thread is either initialized or aborted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
      Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
      MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
      while ((state = osthread->get_state()) == ALLOCATED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
        sync_with_child->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
      os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  // Aborted due to thread limit being reached
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  if (state == ZOMBIE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  // The thread is returned suspended (in state INITIALIZED),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  // and is started higher up in the call chain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  assert(state == INITIALIZED, "race condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
// attach existing thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
// bootstrap the main thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
bool os::create_main_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  return create_attached_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
bool os::create_attached_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    thread->verify_not_published();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  osthread->set_pthread_id(::pthread_self());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  // Initial thread state is RUNNABLE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  osthread->set_state(RUNNABLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  if (os::Linux::is_initial_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
    // If current thread is initial thread, its stack is mapped on demand,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
    // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    // the entire stack region to avoid SEGV in stack banging.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    // It is also useful to get around the heap-stack-gap problem on SuSE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    // kernel (see 4821821 for details). We first expand stack to the top
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
    // of yellow zone, then enable stack yellow zone (order is significant,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
    // enabling yellow zone first will crash JVM on SuSE Linux), so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
    // is no gap between the last two virtual memory regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    address addr = jt->stack_yellow_zone_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    assert(addr != NULL, "initialization problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    osthread->set_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    os::Linux::manually_expand_stack(jt, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    osthread->clear_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  // and save the caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
void os::pd_start_thread(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
  OSThread * osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  assert(osthread->get_state() != INITIALIZED, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  sync_with_child->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
// Free Linux resources related to the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
void os::free_thread(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  assert(osthread != NULL, "osthread not set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  if (Thread::current()->osthread() == osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // Restore caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    sigset_t sigmask = osthread->caller_sigmask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
// thread local storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
int os::allocate_thread_local_storage() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  pthread_key_t key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  int rslt = pthread_key_create(&key, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  assert(rslt == 0, "cannot allocate thread local storage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  return (int)key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
// Note: This is currently not used by VM, as we don't destroy TLS key
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
// on VM exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
void os::free_thread_local_storage(int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  int rslt = pthread_key_delete((pthread_key_t)index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  assert(rslt == 0, "invalid index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
void os::thread_local_storage_at_put(int index, void* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  int rslt = pthread_setspecific((pthread_key_t)index, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  assert(rslt == 0, "pthread_setspecific failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
extern "C" Thread* get_thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  return ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
// initial thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
// Check if current thread is the initial thread, similar to Solaris thr_main.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
bool os::Linux::is_initial_thread(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  char dummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  // If called before init complete, thread stack bottom will be null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  // Can be called if fatal error occurs before initialization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  if (initial_thread_stack_bottom() == NULL) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  assert(initial_thread_stack_bottom() != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
         initial_thread_stack_size()   != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
         "os::init did not locate initial thread's stack region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  if ((address)&dummy >= initial_thread_stack_bottom() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
      (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
       return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  else return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
// Find the virtual memory area that contains addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
static bool find_vma(address addr, address* vma_low, address* vma_high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  FILE *fp = fopen("/proc/self/maps", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
    address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
    while (!feof(fp)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      if (fscanf(fp, "%p-%p", &low, &high) == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
        if (low <= addr && addr < high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
           if (vma_low)  *vma_low  = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
           if (vma_high) *vma_high = high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
           fclose (fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
      for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
        int ch = fgetc(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
        if (ch == EOF || ch == (int)'\n') break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
// Locate initial thread stack. This special handling of initial thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
// is needed because pthread_getattr_np() on most (all?) Linux distros returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
// bogus value for initial thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
void os::Linux::capture_initial_stack(size_t max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  // stack size is the easy part, get it from RLIMIT_STACK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  size_t stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  struct rlimit rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  getrlimit(RLIMIT_STACK, &rlim);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  stack_size = rlim.rlim_cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  // 6308388: a bug in ld.so will relocate its own .data section to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  //   lower end of primordial stack; reduce ulimit -s value a little bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  //   so we won't install guard page on ld.so's data section.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  stack_size -= 2 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
  // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
  //   7.1, in both cases we will get 2G in return value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  //   SuSE 7.2, Debian) can not handle alternate signal stack correctly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  //   for initial thread if its stack size exceeds 6M. Cap it at 2M,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
  //   in case other parts in glibc still assumes 2M max stack size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  // FIXME: alt signal stack is gone, maybe we can relax this constraint?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
15475
73896d91270c 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 15234
diff changeset
  1157
  if (stack_size > 2 * K * K IA64_ONLY(*2))
73896d91270c 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 15234
diff changeset
  1158
      stack_size = 2 * K * K IA64_ONLY(*2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  // Try to figure out where the stack base (top) is. This is harder.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  // When an application is started, glibc saves the initial stack pointer in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  // a global variable "__libc_stack_end", which is then used by system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  // libraries. __libc_stack_end should be pretty close to stack top. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  // variable is available since the very early days. However, because it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  // a private interface, it could disappear in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  // to __libc_stack_end, it is very close to stack top, but isn't the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  // stack top. Note that /proc may not exist if VM is running as a chroot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  // program, so reading /proc/<pid>/stat could fail. Also the contents of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  // /proc/<pid>/stat could change in the future (though unlikely).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
  // We try __libc_stack_end first. If that doesn't work, look for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  // /proc/<pid>/stat. If neither of them works, we use current stack pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  // as a hint, which should work well in most cases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  uintptr_t stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
  // try __libc_stack_end first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  if (p && *p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
    stack_start = *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    // see if we can get the start_stack field from /proc/self/stat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    int pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    char state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
    int ppid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    int pgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    int session;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    int nr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    int tpgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    unsigned long flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    unsigned long minflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
    unsigned long cminflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
    unsigned long majflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    unsigned long cmajflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
    unsigned long utime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
    unsigned long stime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    long cutime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    long cstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    long prio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    long nice;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
    long junk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    long it_real;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
    uintptr_t start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    uintptr_t vsize;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1208
    intptr_t rss;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1209
    uintptr_t rsslim;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    uintptr_t scodes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
    uintptr_t ecode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
    // Figure what the primordial thread stack base is. Code is inspired
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    // by email from Hans Boehm. /proc/self/stat begins with current pid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
    // followed by command name surrounded by parentheses, state, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
    fp = fopen("/proc/self/stat", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
    if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
      statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
      // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
      // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
      //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
      // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
      // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
      char * s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      if (s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
        // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
        do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1239
#define _UFM UINTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1240
#define _DFM INTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1241
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1242
        /*                                     1   1   1   1   1   1   1   1   1   1   2   2    2    2    2    2    2    2    2 */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1243
        /*              3  4  5  6  7  8   9   0   1   2   3   4   5   6   7   8   9   0   1    2    3    4    5    6    7    8 */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1244
        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
             &state,          /* 3  %c  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
             &ppid,           /* 4  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
             &pgrp,           /* 5  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
             &session,        /* 6  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
             &nr,             /* 7  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
             &tpgrp,          /* 8  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
             &flags,          /* 9  %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
             &minflt,         /* 10 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
             &cminflt,        /* 11 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
             &majflt,         /* 12 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
             &cmajflt,        /* 13 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
             &utime,          /* 14 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
             &stime,          /* 15 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
             &cutime,         /* 16 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
             &cstime,         /* 17 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
             &prio,           /* 18 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
             &nice,           /* 19 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
             &junk,           /* 20 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
             &it_real,        /* 21 %ld  */
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1264
             &start,          /* 22 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1265
             &vsize,          /* 23 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1266
             &rss,            /* 24 INTX_FORMAT  */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1267
             &rsslim,         /* 25 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1268
             &scodes,         /* 26 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1269
             &ecode,          /* 27 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1270
             &stack_start);   /* 28 UINTX_FORMAT */
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1273
#undef _UFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1274
#undef _DFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1275
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
      if (i != 28 - 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
         assert(false, "Bad conversion from /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
         // product mode - assume we are the initial thread, good luck in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
         // embedded case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
         warning("Can't detect initial thread stack location - bad conversion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
         stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
      // For some reason we can't open /proc/self/stat (for example, running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
      // FreeBSD with a Linux emulator, or inside chroot), this should work for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
      // most cases, so don't abort:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
      warning("Can't detect initial thread stack location - no /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  // Now we have a pointer (stack_start) very close to the stack top, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // next thing to do is to figure out the exact location of stack top. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  // can find out the virtual memory area that contains stack_start by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
  // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  // and its upper limit is the real stack top. (again, this would fail if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  // running inside chroot, because /proc may not exist.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  uintptr_t stack_top;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  if (find_vma((address)stack_start, &low, &high)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    // success, "high" is the true stack top. (ignore "low", because initial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
    stack_top = (uintptr_t)high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    // failed, likely because /proc/self/maps does not exist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
    warning("Can't detect initial thread stack location - find_vma failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
    // best effort: stack_start is normally within a few pages below the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    // stack top, use it as stack top, and reduce stack size so we won't put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    // guard page outside stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
    stack_top = stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
    stack_size -= 16 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  // stack_top could be partially down the page so align it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  stack_top = align_size_up(stack_top, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
  if (max_size && stack_size > max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
     _initial_thread_stack_size = max_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
     _initial_thread_stack_size = stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
  _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
// time support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
// Time since start-up in seconds to a fine granularity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
// Used by VMSelfDestructTimer and the MemProfiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
double os::elapsedTime() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  return (double)(os::elapsed_counter()) * 0.000001;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
jlong os::elapsed_counter() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
  return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
jlong os::elapsed_frequency() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  return (1000 * 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1348
bool os::supports_vtime() { return true; }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1349
bool os::enable_vtime()   { return false; }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1350
bool os::vtime_enabled()  { return false; }
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1351
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1352
double os::elapsedVTime() {
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1353
  struct rusage usage;
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1354
  int retval = getrusage(RUSAGE_THREAD, &usage);
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1355
  if (retval == 0) {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1356
    return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1357
  } else {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1358
    // better than nothing, but not much
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1359
    return elapsedTime();
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1360
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1361
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1362
234
4da9c1bbc810 6667833: Remove CacheTimeMillis
sbohne
parents: 1
diff changeset
  1363
jlong os::javaTimeMillis() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
#ifndef CLOCK_MONOTONIC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
#define CLOCK_MONOTONIC (1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
void os::Linux::clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  // we do dlopen's in this particular order due to bug in linux
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  // dynamical loader (see 6348968) leading to crash on exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  void* handle = dlopen("librt.so.1", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  if (handle == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
    handle = dlopen("librt.so", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  if (handle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
    int (*clock_getres_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
    int (*clock_gettime_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
    if (clock_getres_func && clock_gettime_func) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
      // See if monotonic clock is supported by the kernel. Note that some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
      // early implementations simply return kernel jiffies (updated every
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
      // 1/100 or 1/1000 second). It would be bad to use such a low res clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
      // for nano time (though the monotonic property is still nice to have).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
      // It's fixed in newer kernels, however clock_getres() still returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
      // 1/HZ. We check if clock_getres() works, but will ignore its reported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
      // resolution for now. Hopefully as people move to new kernels, this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
      // won't be a problem.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
      struct timespec res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
      struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
      if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
          clock_gettime_func(CLOCK_MONOTONIC, &tp)  == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
        // yes, monotonic clock is supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
        _clock_gettime = clock_gettime_func;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
        // close librt if there is no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
        dlclose(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
#ifndef SYS_clock_getres
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
#if defined(IA32) || defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
#define SYS_clock_getres IA32_ONLY(266)  AMD64_ONLY(229)
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1414
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
#else
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1416
#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1417
#define sys_clock_getres(x,y)  -1
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1420
#else
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1421
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
void os::Linux::fast_thread_clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
  if (!UseLinuxPosixThreadCPUClocks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
      (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  // Switch to using fast clocks for thread cpu time if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  // the sys_clock_getres() returns 0 error code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
  // Note, that some kernels may support the current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  // returned by the pthread_getcpuclockid().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
  // If the fast Posix clocks are supported then the sys_clock_getres()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  // must return at least tp.tv_sec == 0 which means a resolution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  // better than 1 sec. This is extra check for reliability.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  if(pthread_getcpuclockid_func &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
     pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
     sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
    _supports_fast_thread_cpu_time = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
    _pthread_getcpuclockid = pthread_getcpuclockid_func;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
jlong os::javaTimeNanos() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
    struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
    int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
    assert(status == 0, "gettime error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
    jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
    int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
    assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
    jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
    return 1000 * usecs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
    // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
    info_ptr->may_skip_backward = false;      // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
    info_ptr->may_skip_forward = false;       // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
    // gettimeofday - based on time in seconds since the Epoch thus does not wrap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
    // gettimeofday is a real time clock so it skips
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
    info_ptr->may_skip_backward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    info_ptr->may_skip_forward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
  info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
// Return the real, user, and system times in seconds from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
// arbitrary fixed point in the past.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
bool os::getTimesSecs(double* process_real_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
                      double* process_user_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
                      double* process_system_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
  struct tms ticks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
  clock_t real_ticks = times(&ticks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
  if (real_ticks == (clock_t) (-1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
    double ticks_per_second = (double) clock_tics_per_sec;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
    *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
    *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
    *process_real_time = ((double) real_ticks) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
char * os::local_time_string(char *buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
  struct tm t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
  time_t long_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  time(&long_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
  localtime_r(&long_time, &t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
               t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
               t.tm_hour, t.tm_min, t.tm_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
2012
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1518
struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1519
  return localtime_r(clock, res);
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1520
}
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1521
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
// runtime exit support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
// Note: os::shutdown() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
// called from signal handler. Before adding something to os::shutdown(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
void os::shutdown() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
  // allow PerfMemory to attempt cleanup of any persistent resources
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
  perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
  // needs to remove object in file system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
  AttachListener::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  // flush buffered output, finish log files
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
  ostream_abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
  // Check for abort hook
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
  abort_hook_t abort_hook = Arguments::abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
  if (abort_hook != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
// Note: os::abort() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
// called from signal handler. Before adding something to os::abort(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
void os::abort(bool dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  os::shutdown();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  if (dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
    fdStream out(defaultStream::output_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    out.print_raw("Current thread is ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
    char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    out.print_raw_cr(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    out.print_raw_cr("Dumping core ...");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    ::abort(); // dump core
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
  ::exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
// Die immediately, no exit hook, no abort hook, no cleanup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
void os::die() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  // _exit() on LinuxThreads only kills current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  ::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
// unused on linux for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
void os::set_error_file(const char *logfile) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1576
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1577
// This method is a copy of JDK's sysGetLastErrorString
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1578
// from src/solaris/hpi/src/system_md.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1579
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1580
size_t os::lasterror(char *buf, size_t len) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1581
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1582
  if (errno == 0)  return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1583
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1584
  const char *s = ::strerror(errno);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1585
  size_t n = ::strlen(s);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1586
  if (n >= len) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1587
    n = len - 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1588
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1589
  ::strncpy(buf, s, n);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1590
  buf[n] = '\0';
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1591
  return n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1592
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1593
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
intx os::current_thread_id() { return (intx)pthread_self(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
int os::current_process_id() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
  // Under the old linux thread library, linux gives each thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
  // its own process id. Because of this each thread will return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  // a different pid if this method were to return the result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  // of getpid(2). Linux provides no api that returns the pid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  // of the launcher thread for the vm. This implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  // returns a unique pid, the pid of the launcher thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
  // that starts the vm 'process'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
  // Under the NPTL, getpid() returns the same pid as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
  // launcher thread rather than a unique pid per thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  // Use gettid() if you want the old pre NPTL behaviour.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  // if you are looking for the result of a call to getpid() that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  // returns a unique pid for the calling thread, then look at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  // OSThread::thread_id() method in osThread_linux.hpp file
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  return (int)(_initial_pid ? _initial_pid : getpid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
// DLL functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
const char* os::dll_file_extension() { return ".so"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
7901
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1620
// This must be hard coded because it's the system's temporary
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1621
// directory not the java application's temp directory, ala java.io.tmpdir.
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1622
const char* os::get_temp_directory() { return "/tmp"; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1624
static bool file_exists(const char* filename) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1625
  struct stat statbuf;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1626
  if (filename == NULL || strlen(filename) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1627
    return false;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1628
  }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1629
  return os::stat(filename, &statbuf) == 0;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1630
}
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1631
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1632
bool os::dll_build_name(char* buffer, size_t buflen,
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1633
                        const char* pname, const char* fname) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1634
  bool retval = false;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1635
  // Copied from libhpi
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1636
  const size_t pnamelen = pname ? strlen(pname) : 0;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1637
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1638
  // Return error on buffer overflow.
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1639
  if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1640
    return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1641
  }
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1642
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1643
  if (pnamelen == 0) {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1644
    snprintf(buffer, buflen, "lib%s.so", fname);
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1645
    retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1646
  } else if (strchr(pname, *os::path_separator()) != NULL) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1647
    int n;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1648
    char** pelements = split_path(pname, &n);
16669
fb3397cee116 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 16438
diff changeset
  1649
    if (pelements == NULL) {
16672
dcubed
parents: 16609 16670
diff changeset
  1650
      return false;
16669
fb3397cee116 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 16438
diff changeset
  1651
    }
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1652
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1653
      // Really shouldn't be NULL, but check can't hurt
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1654
      if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1655
        continue; // skip the empty path values
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1656
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1657
      snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1658
      if (file_exists(buffer)) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1659
        retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1660
        break;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1661
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1662
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1663
    // release the storage
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1664
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1665
      if (pelements[i] != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1666
        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1667
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1668
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1669
    if (pelements != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1670
      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1671
    }
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1672
  } else {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1673
    snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1674
    retval = true;
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1675
  }
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1676
  return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1677
}
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1678
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  1679
// check if addr is inside libjvm.so
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
bool os::address_is_in_vm(address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  static address libjvm_base_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
  if (libjvm_base_addr == NULL) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1685
    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1686
      libjvm_base_addr = (address)dlinfo.dli_fbase;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1687
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
    assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1691
  if (dladdr((void *)addr, &dlinfo) != 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
bool os::dll_address_to_function_name(address addr, char *buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
                                      int buflen, int *offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1700
  // buf is not optional, but offset is optional
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1701
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1702
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1705
  if (dladdr((void*)addr, &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1706
    // see if we have a matching symbol
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1707
    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1708
      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1709
        jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1710
      }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1711
      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1712
      return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1713
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1714
    // no matching symbol so try for just file info
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1715
    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1716
      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1717
                          buf, buflen, offset, dlinfo.dli_fname)) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1718
        return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1719
      }
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1720
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1721
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1722
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1723
  buf[0] = '\0';
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1724
  if (offset != NULL) *offset = -1;
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1725
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
struct _address_to_library_name {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  address addr;          // input : memory address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  size_t  buflen;        //         size of fname
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  char*   fname;         // output: library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  address base;          //         library base addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
static int address_to_library_name_callback(struct dl_phdr_info *info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
                                            size_t size, void *data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
  bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
  address libbase = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
  struct _address_to_library_name * d = (struct _address_to_library_name *)data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  // iterate through all loadable segments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  for (i = 0; i < info->dlpi_phnum; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
    address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
    if (info->dlpi_phdr[i].p_type == PT_LOAD) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
      // base address of a library is the lowest address of its loaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
      // segments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
      if (libbase == NULL || libbase > segbase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
        libbase = segbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
      // see if 'addr' is within current segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
      if (segbase <= d->addr &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
          d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
        found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
  // dlpi_name is NULL or empty if the ELF file is executable, return 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
  // so dll_address_to_library_name() can fall through to use dladdr() which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  // can figure out executable name from argv[0].
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
  if (found && info->dlpi_name && info->dlpi_name[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
    d->base = libbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
    if (d->fname) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
    return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
bool os::dll_address_to_library_name(address addr, char* buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
                                     int buflen, int* offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1774
  // buf is not optional, but offset is optional
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1775
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1776
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  struct _address_to_library_name data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  // There is a bug in old glibc dladdr() implementation that it could resolve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  // to wrong library name if the .so file has a base address != NULL. Here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  // we iterate through the program headers of all loaded libraries to find
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  // out which library 'addr' really belongs to. This workaround can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
  // removed once the minimum requirement for glibc is moved to 2.3.x.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
  data.addr = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  data.fname = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
  data.buflen = buflen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
  data.base = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  if (rslt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
     // buf already contains library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
     if (offset) *offset = addr - data.base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
     return true;
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1795
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1796
  if (dladdr((void*)addr, &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1797
    if (dlinfo.dli_fname != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1798
      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1799
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1800
    if (dlinfo.dli_fbase != NULL && offset != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1801
      *offset = addr - (address)dlinfo.dli_fbase;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1802
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1803
    return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1804
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1805
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1806
  buf[0] = '\0';
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1807
  if (offset) *offset = -1;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1808
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
  // Loads .dll/.so and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  // in case of error it checks if .dll/.so was built for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  // same architecture as Hotspot is running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1815
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1816
// Remember the stack's state. The Linux dynamic linker will change
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1817
// the stack to 'executable' at most once, so we must safepoint only once.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1818
bool os::Linux::_stack_is_executable = false;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1819
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1820
// VM operation that loads a library.  This is necessary if stack protection
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1821
// of the Java stacks can be lost during loading the library.  If we
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1822
// do not stop the Java threads, they can stack overflow before the stacks
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1823
// are protected again.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1824
class VM_LinuxDllLoad: public VM_Operation {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1825
 private:
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1826
  const char *_filename;
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1827
  char *_ebuf;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1828
  int _ebuflen;
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1829
  void *_lib;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1830
 public:
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1831
  VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) :
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1832
    _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {}
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1833
  VMOp_Type type() const { return VMOp_LinuxDllLoad; }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1834
  void doit() {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1835
    _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1836
    os::Linux::_stack_is_executable = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1837
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1838
  void* loaded_library() { return _lib; }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1839
};
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1840
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
{
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1843
  void * result = NULL;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1844
  bool load_attempted = false;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1845
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1846
  // Check whether the library to load might change execution rights
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1847
  // of the stack. If they are changed, the protection of the stack
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1848
  // guard pages will be lost. We need a safepoint to fix this.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1849
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1850
  // See Linux man page execstack(8) for more info.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1851
  if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1852
    ElfFile ef(filename);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1853
    if (!ef.specifies_noexecstack()) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1854
      if (!is_init_completed()) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1855
        os::Linux::_stack_is_executable = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1856
        // This is OK - No Java threads have been created yet, and hence no
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1857
        // stack guard pages to fix.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1858
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1859
        // This should happen only when you are building JDK7 using a very
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1860
        // old version of JDK6 (e.g., with JPRT) and running test_gamma.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1861
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1862
        // Dynamic loader will make all stacks executable after
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1863
        // this function returns, and will not do that again.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1864
        assert(Threads::first() == NULL, "no Java threads should exist yet.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1865
      } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1866
        warning("You have loaded library %s which might have disabled stack guard. "
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1867
                "The VM will try to fix the stack guard now.\n"
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1868
                "It's highly recommended that you fix the library with "
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1869
                "'execstack -c <libfile>', or link it with '-z noexecstack'.",
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1870
                filename);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1871
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1872
        assert(Thread::current()->is_Java_thread(), "must be Java thread");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1873
        JavaThread *jt = JavaThread::current();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1874
        if (jt->thread_state() != _thread_in_native) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1875
          // This happens when a compiler thread tries to load a hsdis-<arch>.so file
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1876
          // that requires ExecStack. Cannot enter safe point. Let's give up.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1877
          warning("Unable to fix stack guard. Giving up.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1878
        } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1879
          if (!LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1880
            // This is for the case where the DLL has an static
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1881
            // constructor function that executes JNI code. We cannot
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1882
            // load such DLLs in the VMThread.
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1883
            result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1884
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1885
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1886
          ThreadInVMfromNative tiv(jt);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1887
          debug_only(VMNativeEntryWrapper vew;)
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1888
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1889
          VM_LinuxDllLoad op(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1890
          VMThread::execute(&op);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1891
          if (LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1892
            result = op.loaded_library();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1893
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1894
          load_attempted = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1895
        }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1896
      }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1897
    }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1898
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1899
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1900
  if (!load_attempted) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1901
    result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1902
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1903
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
    // Successful loading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  Elf32_Ehdr elf_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  int diag_msg_max_length=ebuflen-strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  char* diag_msg_buf=ebuf+strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  if (diag_msg_max_length==0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
    // No more space in ebuf for additional diagnostics message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
  if (file_descriptor < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
    // Can't open library, report dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  bool failed_to_read_elf_head=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
    (sizeof(elf_head)!=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
        (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  ::close(file_descriptor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  if (failed_to_read_elf_head) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
    // file i/o error - report dlerror() msg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
    Elf32_Half  code;         // Actual value as defined in elf.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
    Elf32_Half  compat_class; // Compatibility of archs at VM's sense
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
    char        elf_class;    // 32 or 64 bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
    char        endianess;    // MSB or LSB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    char*       name;         // String representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  } arch_t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  #ifndef EM_486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  #define EM_486          6               /* Intel 80486 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  static const arch_t arch_array[]={
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
    {EM_386,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
    {EM_486,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
    {EM_IA_64,       EM_IA_64,   ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
    {EM_X86_64,      EM_X86_64,  ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
    {EM_SPARC,       EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    {EM_SPARC32PLUS, EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    {EM_SPARCV9,     EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    {EM_PPC,         EM_PPC,     ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1957
    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1958
    {EM_ARM,         EM_ARM,     ELFCLASS32,   ELFDATA2LSB, (char*)"ARM"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1959
    {EM_S390,        EM_S390,    ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1960
    {EM_ALPHA,       EM_ALPHA,   ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1961
    {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1962
    {EM_MIPS,        EM_MIPS,    ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1963
    {EM_PARISC,      EM_PARISC,  ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1964
    {EM_68K,         EM_68K,     ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  #if  (defined IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
    static  Elf32_Half running_arch_code=EM_386;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  #elif   (defined AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
    static  Elf32_Half running_arch_code=EM_X86_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  #elif  (defined IA64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
    static  Elf32_Half running_arch_code=EM_IA_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  #elif  (defined __sparc) && (defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
    static  Elf32_Half running_arch_code=EM_SPARCV9;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  #elif  (defined __sparc) && (!defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    static  Elf32_Half running_arch_code=EM_SPARC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  #elif  (defined __powerpc64__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
    static  Elf32_Half running_arch_code=EM_PPC64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
  #elif  (defined __powerpc__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
    static  Elf32_Half running_arch_code=EM_PPC;
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1981
  #elif  (defined ARM)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1982
    static  Elf32_Half running_arch_code=EM_ARM;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1983
  #elif  (defined S390)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1984
    static  Elf32_Half running_arch_code=EM_S390;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1985
  #elif  (defined ALPHA)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1986
    static  Elf32_Half running_arch_code=EM_ALPHA;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1987
  #elif  (defined MIPSEL)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1988
    static  Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1989
  #elif  (defined PARISC)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1990
    static  Elf32_Half running_arch_code=EM_PARISC;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1991
  #elif  (defined MIPS)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1992
    static  Elf32_Half running_arch_code=EM_MIPS;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1993
  #elif  (defined M68K)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1994
    static  Elf32_Half running_arch_code=EM_68K;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
  #else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
    #error Method os::dll_load requires that one of following is defined:\
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1997
         IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  // Identify compatability class for VM's architecture and library's architecture
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
  // Obtain string descriptions for architectures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
  int running_arch_index=-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
    if (running_arch_code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
      running_arch_index    = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
    if (lib_arch.code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
      lib_arch.compat_class = arch_array[i].compat_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
      lib_arch.name         = arch_array[i].name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  assert(running_arch_index != -1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
    "Didn't find running architecture code (running_arch_code) in arch_array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  if (running_arch_index == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
    // Even though running architecture detection failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
    // we may still continue with reporting dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
  if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2029
#ifndef S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
  if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
  }
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2034
#endif // !S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
  if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
    if ( lib_arch.name!=NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
        " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
        lib_arch.name, arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
      " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
        lib_arch.code,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
        arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2052
void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2053
  void * result = ::dlopen(filename, RTLD_LAZY);
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2054
  if (result == NULL) {
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2055
    ::strncpy(ebuf, ::dlerror(), ebuflen - 1);
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2056
    ebuf[ebuflen-1] = '\0';
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2057
  }
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2058
  return result;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2059
}
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2060
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2061
void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) {
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2062
  void * result = NULL;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2063
  if (LoadExecStackDllInVMThread) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2064
    result = dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2065
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2066
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2067
  // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2068
  // library that requires an executable stack, or which does not have this
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2069
  // stack attribute set, dlopen changes the stack attribute to executable. The
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2070
  // read protection of the guard pages gets lost.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2071
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2072
  // Need to check _stack_is_executable again as multiple VM_LinuxDllLoad
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2073
  // may have been queued at the same time.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2074
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2075
  if (!_stack_is_executable) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2076
    JavaThread *jt = Threads::first();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2077
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2078
    while (jt) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2079
      if (!jt->stack_guard_zone_unused() &&        // Stack not yet fully initialized
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2080
          jt->stack_yellow_zone_enabled()) {       // No pending stack overflow exceptions
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2081
        if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2082
                              jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2083
          warning("Attempt to reguard stack yellow zone failed.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2084
        }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2085
      }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2086
      jt = jt->next();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2087
    }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2088
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2089
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2090
  return result;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2091
}
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2092
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2093
/*
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2094
 * glibc-2.0 libdl is not MT safe.  If you are building with any glibc,
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2095
 * chances are you might want to run the generated bits against glibc-2.0
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2096
 * libdl.so, so always use locking for any version of glibc.
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2097
 */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2098
void* os::dll_lookup(void* handle, const char* name) {
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2099
  pthread_mutex_lock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2100
  void* res = dlsym(handle, name);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2101
  pthread_mutex_unlock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2102
  return res;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2103
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2106
static bool _print_ascii_file(const char* filename, outputStream* st) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2107
  int fd = ::open(filename, O_RDONLY);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  if (fd == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
     return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  char buf[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
  int bytes;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2114
  while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    st->print_raw(buf, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2118
  ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
void os::print_dll_info(outputStream *st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
   st->print_cr("Dynamic libraries:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
   char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
   pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
   jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
   if (!_print_ascii_file(fname, st)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
     st->print("Can not get library information for pid = %d\n", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2136
void os::print_os_info_brief(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2137
  os::Linux::print_distro_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2138
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2139
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2140
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2141
  os::Linux::print_libversion_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2142
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2143
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
void os::print_os_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
  st->print("OS:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2148
  os::Linux::print_distro_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2149
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2150
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2151
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2152
  // Print warning if unsafe chroot environment detected
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2153
  if (unsafe_chroot_detected) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2154
    st->print("WARNING!! ");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2155
    st->print_cr(unstable_chroot_error);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2156
  }
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2157
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2158
  os::Linux::print_libversion_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2159
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2160
  os::Posix::print_rlimit_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2161
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2162
  os::Posix::print_load_average(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2163
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2164
  os::Linux::print_full_memory_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2165
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2166
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2167
// Try to identify popular distros.
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2168
// Most Linux distributions have /etc/XXX-release file, which contains
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2169
// the OS version string. Some have more than one /etc/XXX-release file
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2170
// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2171
// so the order is important.
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2172
void os::Linux::print_distro_info(outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
  if (!_print_ascii_file("/etc/mandrake-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
      !_print_ascii_file("/etc/sun-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
      !_print_ascii_file("/etc/redhat-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
      !_print_ascii_file("/etc/SuSE-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
      !_print_ascii_file("/etc/turbolinux-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
      !_print_ascii_file("/etc/gentoo-release", st) &&
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2179
      !_print_ascii_file("/etc/debian_version", st) &&
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2180
      !_print_ascii_file("/etc/ltib-release", st) &&
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2181
      !_print_ascii_file("/etc/angstrom-version", st)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
      st->print("Linux");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
  st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2185
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2186
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2187
void os::Linux::print_libversion_info(outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  // libc, pthread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  st->print("libc:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
  st->print(os::Linux::glibc_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
  st->print(os::Linux::libpthread_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
  if (os::Linux::is_LinuxThreads()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
     st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
  st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2196
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2197
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2198
void os::Linux::print_full_memory_info(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2199
   st->print("\n/proc/meminfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2200
   _print_ascii_file("/proc/meminfo", st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2201
   st->cr();
10023
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2202
}
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2203
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
void os::print_memory_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
  st->print("Memory:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
  st->print(" %dk page", os::vm_page_size()>>10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
  st->print(", physical " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
            os::physical_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
            os::available_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  st->print(", swap " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
            ((jlong)si.totalswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
            ((jlong)si.freeswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2224
void os::pd_print_cpu_info(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2225
  st->print("\n/proc/cpuinfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2226
  if (!_print_ascii_file("/proc/cpuinfo", st)) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2227
    st->print("  <Not Available>");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2228
  }
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2229
  st->cr();
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2230
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2231
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
// Taken from /usr/include/bits/siginfo.h  Supposed to be architecture specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
// but they're the same for all the linux arch that we support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
// and they're the same for solaris but there's no common place to put this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
                          "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
                          "ILL_COPROC", "ILL_BADSTK" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
                          "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
                          "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
void os::print_siginfo(outputStream* st, void* siginfo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
  st->print("siginfo:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
  const int buflen = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  char buf[buflen];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
  siginfo_t *si = (siginfo_t*)siginfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
  st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
  if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
    st->print("si_errno=%s", buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
    st->print("si_errno=%d", si->si_errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
  const int c = si->si_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
  assert(c > 0, "unexpected si_code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  switch (si->si_signo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
    st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
    st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
    st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
    st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
    st->print(", si_code=%d", si->si_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
    // no si_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
      UseSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
    FileMapInfo* mapinfo = FileMapInfo::current_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
    if (mapinfo->is_in_shared_space(si->si_addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
      st->print("\n\nError accessing class data sharing archive."   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
                " Mapped file inaccessible during execution, "      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
                " possible disk/network problem.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
                                 char* buf, size_t buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  st->print_cr("Signal Handlers:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
  print_signal_handler(st, SIGSEGV, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
  print_signal_handler(st, SIGBUS , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
  print_signal_handler(st, SIGFPE , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  print_signal_handler(st, SIGPIPE, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
  print_signal_handler(st, SIGXFSZ, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
  print_signal_handler(st, SIGILL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  print_signal_handler(st, SR_signum, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
static char saved_jvm_path[MAXPATHLEN] = {0};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2317
// Find the full path to the current module, libjvm.so
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2318
void os::jvm_path(char *buf, jint buflen) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
  // Error checking.
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2320
  if (buflen < MAXPATHLEN) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
    assert(false, "must use a large-enough buffer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
    buf[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  // Lazy resolve the path to current module.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
  if (saved_jvm_path[0] != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
    strcpy(buf, saved_jvm_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
  char dli_fname[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
  bool ret = dll_address_to_library_name(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
                CAST_FROM_FN_PTR(address, os::jvm_path),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
                dli_fname, sizeof(dli_fname), NULL);
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2335
  assert(ret, "cannot locate libjvm");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2336
  char *rp = NULL;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2337
  if (ret && dli_fname[0] != '\0') {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2338
    rp = realpath(dli_fname, buf);
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2339
  }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2340
  if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2341
    return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
8476
7e34c2d4cf9b 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 8119
diff changeset
  2343
  if (Arguments::created_by_gamma_launcher()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
    // Support for the gamma launcher.  Typical value for buf is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
    // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
    // the right place in the string, then assume we are installed in a JDK and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
    // we're done.  Otherwise, check for a JAVA_HOME environment variable and fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
    // up the path so it looks like libjvm.so is installed there (append a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
    // fake suffix hotspot/libjvm.so).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
    const char *p = buf + strlen(buf) - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
    for (int count = 0; p > buf && count < 5; ++count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
      for (--p; p > buf && *p != '/'; --p)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
        /* empty */ ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
    if (strncmp(p, "/jre/lib/", 9) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
      // Look for JAVA_HOME in the environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      char* java_home_var = ::getenv("JAVA_HOME");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      if (java_home_var != NULL && java_home_var[0] != 0) {
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2360
        char* jrelib_p;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2361
        int len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2362
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2363
        // Check the current module name "libjvm.so".
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
        p = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
        assert(strstr(p, "/libjvm") == p, "invalid library name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2367
        rp = realpath(java_home_var, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2368
        if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2369
          return;
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2370
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2371
        // determine if this is a legacy image or modules image
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2372
        // modules image doesn't have "jre" subdirectory
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2373
        len = strlen(buf);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2374
        jrelib_p = buf + len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2375
        snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2376
        if (0 != access(buf, F_OK)) {
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2377
          snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2378
        }
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2379
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
        if (0 == access(buf, F_OK)) {
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2381
          // Use current module name "libjvm.so"
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2382
          len = strlen(buf);
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2383
          snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
          // Go back to path of .so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2386
          rp = realpath(dli_fname, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2387
          if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2388
            return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
  strcpy(saved_jvm_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
  // no prefix required, not even "_"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
  // no suffix required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
// sun.misc.Signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
static volatile jint sigint_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
static void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
UserHandler(int sig, void *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
  // 4511530 - sem_post is serialized and handled by the manager thread. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
  // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  // don't want to flood the manager thread with sem_post requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
  if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  // Ctrl-C is pressed during error reporting, likely because the error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
  // handler fails to abort. Let VM die immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
  if (sig == SIGINT && is_error_reported()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
     os::die();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
  os::signal_notify(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
void* os::user_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  return CAST_FROM_FN_PTR(void*, UserHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2431
class Semaphore : public StackObj {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2432
  public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2433
    Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2434
    ~Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2435
    void signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2436
    void wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2437
    bool trywait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2438
    bool timedwait(unsigned int sec, int nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2439
  private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2440
    sem_t _semaphore;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2441
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2442
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2443
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2444
Semaphore::Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2445
  sem_init(&_semaphore, 0, 0);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2446
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2447
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2448
Semaphore::~Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2449
  sem_destroy(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2450
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2451
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2452
void Semaphore::signal() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2453
  sem_post(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2454
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2455
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2456
void Semaphore::wait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2457
  sem_wait(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2458
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2459
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2460
bool Semaphore::trywait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2461
  return sem_trywait(&_semaphore) == 0;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2462
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2463
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2464
bool Semaphore::timedwait(unsigned int sec, int nsec) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2465
  struct timespec ts;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2466
  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2467
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2468
  while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2469
    int result = sem_timedwait(&_semaphore, &ts);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2470
    if (result == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2471
      return true;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2472
    } else if (errno == EINTR) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2473
      continue;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2474
    } else if (errno == ETIMEDOUT) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2475
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2476
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2477
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2478
    }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2479
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2480
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2481
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
  typedef void (*sa_handler_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
  typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
void* os::signal(int signal_number, void* handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
  struct sigaction sigAct, oldSigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  sigAct.sa_flags   = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
  if (sigaction(signal_number, &sigAct, &oldSigAct)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
    // -1 means registration failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
    return (void *)-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
  return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
void os::signal_raise(int signal_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
  ::raise(signal_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
 * The following code is moved from os.cpp for making this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
 * code platform specific, which it is by its very nature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
// Will be modified when max signal is changed to be dynamic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
int os::sigexitnum_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
  return NSIG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
// a counter for each possible signal value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
static volatile jint pending_signals[NSIG+1] = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
// Linux(POSIX) specific hand shaking semaphore.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
static sem_t sig_sem;
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2521
static Semaphore sr_semaphore;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
void os::signal_init_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
  // Initialize signal structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
  ::memset((void*)pending_signals, 0, sizeof(pending_signals));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
  // Initialize signal semaphore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  ::sem_init(&sig_sem, 0, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
void os::signal_notify(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
  Atomic::inc(&pending_signals[sig]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
static int check_pending_signals(bool wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  Atomic::store(0, &sigint_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
    for (int i = 0; i < NSIG + 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
      jint n = pending_signals[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
        return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
    if (!wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
      return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
    JavaThread *thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
    ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
    bool threadIsSuspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
      thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
      ::sem_wait(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
      // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
      if (threadIsSuspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
        // The semaphore has been incremented, but while we were waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
        // another thread suspended us. We don't want to continue running
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
        // while suspended because that would surprise the thread that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
        // suspended us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
        ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
        thread->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
    } while (threadIsSuspended);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
int os::signal_lookup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
  return check_pending_signals(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
int os::signal_wait() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
  return check_pending_signals(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
// Virtual Memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
int os::vm_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  // Seems redundant as all get out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
// Solaris allocates memory by pages.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
int os::vm_allocation_granularity() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
// Rationale behind this function:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
//  current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
//  mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
//  samples for JITted code. Here we create private executable mapping over the code cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
//  and then we can use standard (well, almost, as mapping can change) way to provide
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
//  info for the reporting script by storing timestamp and location of symbol
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
void linux_wrap_code(char* base, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  static volatile jint cnt = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
  if (!UseOprofile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
5410
c4b979417733 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 5237
diff changeset
  2610
  char buf[PATH_MAX+1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
  int num = Atomic::add(1, &cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5090
diff changeset
  2613
  snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5090
diff changeset
  2614
           os::get_temp_directory(), os::current_process_id(), num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
  unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2617
  int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  if (fd != -1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2620
    off_t rv = ::lseek(fd, size-2, SEEK_SET);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
    if (rv != (off_t)-1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2622
      if (::write(fd, "", 1) == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
        mmap(base, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
             PROT_READ|PROT_WRITE|PROT_EXEC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
             MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2628
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
    unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2633
static bool recoverable_mmap_error(int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2634
  // See if the error is one we can let the caller handle. This
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2635
  // list of errno values comes from JBS-6843484. I can't find a
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2636
  // Linux man page that documents this specific set of errno
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2637
  // values so while this list currently matches Solaris, it may
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2638
  // change as we gain experience with this failure mode.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2639
  switch (err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2640
  case EBADF:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2641
  case EINVAL:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2642
  case ENOTSUP:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2643
    // let the caller deal with these errors
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2644
    return true;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2645
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2646
  default:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2647
    // Any remaining errors on this OS can cause our reserved mapping
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2648
    // to be lost. That can cause confusion where different data
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2649
    // structures think they have the same memory mapped. The worst
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2650
    // scenario is if both the VM and a library think they have the
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2651
    // same memory mapped.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2652
    return false;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2653
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2654
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2655
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2656
static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2657
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2658
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2659
          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2660
          strerror(err), err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2661
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2662
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2663
static void warn_fail_commit_memory(char* addr, size_t size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2664
                                    size_t alignment_hint, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2665
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2666
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2667
          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2668
          alignment_hint, exec, strerror(err), err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2669
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2670
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
// NOTE: Linux kernel does not really reserve the pages for us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
//       All it does is to check if there are enough free pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
//       left at the time of mmap(). This could be a potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
//       problem.
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2675
int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
2268
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  2676
  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  2677
  uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
                                   MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2679
  if (res != (uintptr_t) MAP_FAILED) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2680
    if (UseNUMAInterleaving) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2681
      numa_make_global(addr, size);
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2682
    }
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2683
    return 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2684
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2685
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2686
  int err = errno;  // save errno from mmap() call above
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2687
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2688
  if (!recoverable_mmap_error(err)) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2689
    warn_fail_commit_memory(addr, size, exec, err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2690
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2691
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2692
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2693
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2694
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2695
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2696
bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2697
  return os::Linux::commit_memory_impl(addr, size, exec) == 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2698
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2699
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2700
void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2701
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2702
  assert(mesg != NULL, "mesg must be specified");
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2703
  int err = os::Linux::commit_memory_impl(addr, size, exec);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2704
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2705
    // the caller wants all commit errors to exit with the specified mesg:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2706
    warn_fail_commit_memory(addr, size, exec, err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2707
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2708
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2711
// Define MAP_HUGETLB here so we can build HotSpot on old systems.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2712
#ifndef MAP_HUGETLB
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2713
#define MAP_HUGETLB 0x40000
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2714
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2715
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2716
// Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2717
#ifndef MADV_HUGEPAGE
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2718
#define MADV_HUGEPAGE 14
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2719
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2720
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2721
int os::Linux::commit_memory_impl(char* addr, size_t size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2722
                                  size_t alignment_hint, bool exec) {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  2723
  int err = os::Linux::commit_memory_impl(addr, size, exec);
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2724
  if (err == 0) {
10522
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2725
    realign_memory(addr, size, alignment_hint);
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2726
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2727
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2728
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2729
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2730
bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2731
                          bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2732
  return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2733
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2734
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2735
void os::pd_commit_memory_or_exit(char* addr, size_t size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2736
                                  size_t alignment_hint, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2737
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2738
  assert(mesg != NULL, "mesg must be specified");
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2739
  int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2740
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2741
    // the caller wants all commit errors to exit with the specified mesg:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2742
    warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2743
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2744
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2747
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  2748
  if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2749
    // We don't check the return value: madvise(MADV_HUGEPAGE) may not
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2750
    // be supported or the memory may already be backed by huge pages.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2751
    ::madvise(addr, bytes, MADV_HUGEPAGE);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2752
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2753
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2754
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2755
void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
12116
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2756
  // This method works by doing an mmap over an existing mmaping and effectively discarding
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2757
  // the existing pages. However it won't work for SHM-based large pages that cannot be
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2758
  // uncommitted at all. We don't do anything in this case to avoid creating a segment with
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2759
  // small pages on top of the SHM segment. This method always works for small pages, so we
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2760
  // allow that in any case.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  2761
  if (alignment_hint <= (size_t)os::vm_page_size() || can_commit_large_page_memory()) {
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2762
    commit_memory(addr, bytes, alignment_hint, !ExecMem);
12116
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2763
  }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2764
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2765
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2766
void os::numa_make_global(char *addr, size_t bytes) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2767
  Linux::numa_interleave_memory(addr, bytes);
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2768
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2769
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2770
// Define for numa_set_bind_policy(int). Setting the argument to 0 will set the
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2771
// bind policy to MPOL_PREFERRED for the current thread.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2772
#define USE_MPOL_PREFERRED 0
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2773
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2774
void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2775
  // To make NUMA and large pages more robust when both enabled, we need to ease
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2776
  // the requirements on where the memory should be allocated. MPOL_BIND is the
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2777
  // default policy and it will force memory to be allocated on the specified
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2778
  // node. Changing this to MPOL_PREFERRED will prefer to allocate the memory on
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2779
  // the specified node, but will not force it. Using this policy will prevent
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2780
  // getting SIGBUS when trying to allocate large pages on NUMA nodes with no
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2781
  // free large pages.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2782
  Linux::numa_set_bind_policy(USE_MPOL_PREFERRED);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2783
  Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2784
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2785
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2786
bool os::numa_topology_changed()   { return false; }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2787
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2788
size_t os::numa_get_groups_num() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2789
  int max_node = Linux::numa_max_node();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2790
  return max_node > 0 ? max_node + 1 : 1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2791
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2792
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2793
int os::numa_get_group_id() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2794
  int cpu_id = Linux::sched_getcpu();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2795
  if (cpu_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2796
    int lgrp_id = Linux::get_node_by_cpu(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2797
    if (lgrp_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2798
      return lgrp_id;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2799
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2804
size_t os::numa_get_leaf_groups(int *ids, size_t size) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2805
  for (size_t i = 0; i < size; i++) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2806
    ids[i] = i;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2807
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2808
  return size;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2809
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2810
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
bool os::get_page_info(char *start, page_info* info) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2819
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2820
int os::Linux::sched_getcpu_syscall(void) {
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2821
  unsigned int cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2822
  int retval = -1;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2823
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2824
#if defined(IA32)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2825
# ifndef SYS_getcpu
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2826
# define SYS_getcpu 318
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2827
# endif
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2828
  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2829
#elif defined(AMD64)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2830
// Unfortunately we have to bring all these macros here from vsyscall.h
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2831
// to be able to compile on old linuxes.
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2832
# define __NR_vgetcpu 2
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2833
# define VSYSCALL_START (-10UL << 20)
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2834
# define VSYSCALL_SIZE 1024
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2835
# define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2836
  typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2837
  vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2838
  retval = vgetcpu(&cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2839
#endif
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2840
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2841
  return (retval == -1) ? retval : cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2842
}
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2843
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2844
// Something to do with the numa-aware allocator needs these symbols
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2845
extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2846
extern "C" JNIEXPORT void numa_error(char *where) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2847
extern "C" JNIEXPORT int fork1() { return fork(); }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2848
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2849
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2850
// If we are running with libnuma version > 2, then we should
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2851
// be trying to use symbols with versions 1.1
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2852
// If we are running with earlier version, which did not have symbol versions,
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2853
// we should use the base version.
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2854
void* os::Linux::libnuma_dlsym(void* handle, const char *name) {
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2855
  void *f = dlvsym(handle, name, "libnuma_1.1");
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2856
  if (f == NULL) {
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2857
    f = dlsym(handle, name);
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2858
  }
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2859
  return f;
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2860
}
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2861
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2862
bool os::Linux::libnuma_init() {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2863
  // sched_getcpu() should be in libc.
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2864
  set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2865
                                  dlsym(RTLD_DEFAULT, "sched_getcpu")));
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2866
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2867
  // If it's not, try a direct syscall.
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2868
  if (sched_getcpu() == -1)
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2869
    set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall));
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2870
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2871
  if (sched_getcpu() != -1) { // Does it work?
975
ad7da100aa6a 6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents: 745
diff changeset
  2872
    void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2873
    if (handle != NULL) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2874
      set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2875
                                           libnuma_dlsym(handle, "numa_node_to_cpus")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2876
      set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2877
                                       libnuma_dlsym(handle, "numa_max_node")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2878
      set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2879
                                        libnuma_dlsym(handle, "numa_available")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2880
      set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2881
                                            libnuma_dlsym(handle, "numa_tonode_memory")));
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2882
      set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2883
                                            libnuma_dlsym(handle, "numa_interleave_memory")));
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2884
      set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t,
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2885
                                            libnuma_dlsym(handle, "numa_set_bind_policy")));
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2886
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2887
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2888
      if (numa_available() != -1) {
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2889
        set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2890
        // Create a cpu -> node mapping
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2891
        _cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2892
        rebuild_cpu_to_node_map();
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2893
        return true;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2894
      }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2895
    }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2896
  }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2897
  return false;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2898
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2899
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2900
// rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2901
// The table is later used in get_node_by_cpu().
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2902
void os::Linux::rebuild_cpu_to_node_map() {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2903
  const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2904
                              // in libnuma (possible values are starting from 16,
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2905
                              // and continuing up with every other power of 2, but less
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2906
                              // than the maximum number of CPUs supported by kernel), and
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2907
                              // is a subject to change (in libnuma version 2 the requirements
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2908
                              // are more reasonable) we'll just hardcode the number they use
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2909
                              // in the library.
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2910
  const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2911
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2912
  size_t cpu_num = os::active_processor_count();
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2913
  size_t cpu_map_size = NCPUS / BitsPerCLong;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2914
  size_t cpu_map_valid_size =
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2915
    MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2916
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2917
  cpu_to_node()->clear();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2918
  cpu_to_node()->at_grow(cpu_num - 1);
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2919
  size_t node_num = numa_get_groups_num();
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2920
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2921
  unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal);
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2922
  for (size_t i = 0; i < node_num; i++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2923
    if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2924
      for (size_t j = 0; j < cpu_map_valid_size; j++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2925
        if (cpu_map[j] != 0) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2926
          for (size_t k = 0; k < BitsPerCLong; k++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2927
            if (cpu_map[j] & (1UL << k)) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2928
              cpu_to_node()->at_put(j * BitsPerCLong + k, i);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2929
            }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2930
          }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2931
        }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2932
      }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2933
    }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2934
  }
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2935
  FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2936
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2937
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2938
int os::Linux::get_node_by_cpu(int cpu_id) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2939
  if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2940
    return cpu_to_node()->at(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2941
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2942
  return -1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2943
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2944
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2945
GrowableArray<int>* os::Linux::_cpu_to_node;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2946
os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2947
os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2948
os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2949
os::Linux::numa_available_func_t os::Linux::_numa_available;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2950
os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2951
os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2952
os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy;
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2953
unsigned long* os::Linux::_numa_all_nodes;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2954
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2955
bool os::pd_uncommit_memory(char* addr, size_t size) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2956
  uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2957
                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2958
  return res  != (uintptr_t) MAP_FAILED;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2961
static
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2962
address get_stack_commited_bottom(address bottom, size_t size) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2963
  address nbot = bottom;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2964
  address ntop = bottom + size;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2965
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2966
  size_t page_sz = os::vm_page_size();
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2967
  unsigned pages = size / page_sz;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2968
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2969
  unsigned char vec[1];
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2970
  unsigned imin = 1, imax = pages + 1, imid;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2971
  int mincore_return_value;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2972
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2973
  while (imin < imax) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2974
    imid = (imax + imin) / 2;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2975
    nbot = ntop - (imid * page_sz);
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2976
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2977
    // Use a trick with mincore to check whether the page is mapped or not.
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2978
    // mincore sets vec to 1 if page resides in memory and to 0 if page
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2979
    // is swapped output but if page we are asking for is unmapped
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2980
    // it returns -1,ENOMEM
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2981
    mincore_return_value = mincore(nbot, page_sz, vec);
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2982
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2983
    if (mincore_return_value == -1) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2984
      // Page is not mapped go up
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2985
      // to find first mapped page
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2986
      if (errno != EAGAIN) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2987
        assert(errno == ENOMEM, "Unexpected mincore errno");
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2988
        imax = imid;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2989
      }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2990
    } else {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2991
      // Page is mapped go down
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2992
      // to find first not mapped page
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2993
      imin = imid + 1;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2994
    }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2995
  }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2996
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2997
  nbot = nbot + page_sz;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2998
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2999
  // Adjust stack bottom one page up if last checked page is not mapped
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3000
  if (mincore_return_value == -1) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3001
    nbot = nbot + page_sz;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3002
  }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3003
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3004
  return nbot;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3005
}
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3006
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3007
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3008
// Linux uses a growable mapping for the stack, and if the mapping for
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3009
// the stack guard pages is not removed when we detach a thread the
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3010
// stack cannot grow beyond the pages where the stack guard was
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3011
// mapped.  If at some point later in the process the stack expands to
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3012
// that point, the Linux kernel cannot expand the stack any further
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3013
// because the guard pages are in the way, and a segfault occurs.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3014
//
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3015
// However, it's essential not to split the stack region by unmapping
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3016
// a region (leaving a hole) that's already part of the stack mapping,
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3017
// so if the stack mapping has already grown beyond the guard pages at
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3018
// the time we create them, we have to truncate the stack mapping.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3019
// So, we need to know the extent of the stack mapping when
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3020
// create_stack_guard_pages() is called.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3021
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3022
// We only need this for stacks that are growable: at the time of
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3023
// writing thread stacks don't use growable mappings (i.e. those
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3024
// creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3025
// only applies to the main thread.
9125
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3026
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3027
// If the (growable) stack mapping already extends beyond the point
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3028
// where we're going to put our guard pages, truncate the mapping at
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3029
// that point by munmap()ping it.  This ensures that when we later
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3030
// munmap() the guard pages we don't leave a hole in the stack
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3031
// mapping. This only affects the main/initial thread
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3032
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3033
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3034
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3035
  if (os::Linux::is_initial_thread()) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3036
    // As we manually grow stack up to bottom inside create_attached_thread(),
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3037
    // it's likely that os::Linux::initial_thread_stack_bottom is mapped and
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3038
    // we don't need to do anything special.
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3039
    // Check it first, before calling heavy function.
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3040
    uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom();
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3041
    unsigned char vec[1];
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3042
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3043
    if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3044
      // Fallback to slow path on all errors, including EAGAIN
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3045
      stack_extent = (uintptr_t) get_stack_commited_bottom(
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3046
                                    os::Linux::initial_thread_stack_bottom(),
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3047
                                    (size_t)addr - stack_extent);
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3048
    }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3049
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3050
    if (stack_extent < (uintptr_t)addr) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3051
      ::munmap((void*)stack_extent, (uintptr_t)(addr - stack_extent));
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3052
    }
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3053
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3054
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3055
  return os::commit_memory(addr, size, !ExecMem);
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3056
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3057
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3058
// If this is a growable mapping, remove the guard pages entirely by
6420
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3059
// munmap()ping them.  If not, just call uncommit_memory(). This only
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3060
// affects the main/initial thread, but guard against future OS changes
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3061
// It's safe to always unmap guard pages for initial thread because we
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3062
// always place it right after end of the mapped region
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3063
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3064
bool os::remove_stack_guard_pages(char* addr, size_t size) {
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3065
  uintptr_t stack_extent, stack_base;
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3066
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3067
  if (os::Linux::is_initial_thread()) {
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3068
    return ::munmap(addr, size) == 0;
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3069
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3070
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3071
  return os::uncommit_memory(addr, size);
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3072
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3073
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
static address _highest_vm_reserved_address = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
// at 'requested_addr'. If there are existing memory mappings at the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
// location, however, they will be overwritten. If 'fixed' is false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
// 'requested_addr' is only treated as a hint, the return value may or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
// may not start from the requested address. Unlike Linux mmap(), this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
// function returns NULL to indicate failure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
  char * addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
  int flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
  flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
  if (fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
    assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
17083
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3092
  // Map reserved/uncommitted pages PROT_NONE so we fail early if we
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3093
  // touch an uncommitted page. Otherwise, the read/write might
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3094
  // succeed if we have enough swap space to back the physical page.
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3095
  addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
                       flags, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
  if (addr != MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
    // anon_mmap() should only get called during VM initialization,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
    // don't need lock (actually we can skip locking even it can be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
    // from multiple threads, because _highest_vm_reserved_address is just a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
    // hint about the upper limit of non-stack memory regions.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
    if ((address)addr + bytes > _highest_vm_reserved_address) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
      _highest_vm_reserved_address = (address)addr + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
  return addr == MAP_FAILED ? NULL : addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
// Don't update _highest_vm_reserved_address, because there might be memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
// regions above addr + size. If so, releasing a memory region only creates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
// a hole in the address space, it doesn't help prevent heap-stack collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
static int anon_munmap(char * addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  return ::munmap(addr, size) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3119
char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
                         size_t alignment_hint) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
  return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3124
bool os::pd_release_memory(char* addr, size_t size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  return anon_munmap(addr, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
static address highest_vm_reserved_address() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
  return _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
static bool linux_mprotect(char* addr, size_t size, int prot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
  // Linux wants the mprotect address argument to be page aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
  char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
  // According to SUSv3, mprotect() should only be used with mappings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
  // established by mmap(), and mmap() always maps whole pages. Unaligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  // 'addr' likely indicates problem in the VM (e.g. trying to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
  // protection of malloc'ed or statically allocated memory). Check the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
  // caller if you hit this assert.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
  assert(addr == bottom, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
  size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
  return ::mprotect(bottom, size, prot) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3147
// Set protections specified
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3148
bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3149
                        bool is_committed) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3150
  unsigned int p = 0;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3151
  switch (prot) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3152
  case MEM_PROT_NONE: p = PROT_NONE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3153
  case MEM_PROT_READ: p = PROT_READ; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3154
  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3155
  case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3156
  default:
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3157
    ShouldNotReachHere();
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3158
  }
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3159
  // is_committed is unused.
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3160
  return linux_mprotect(addr, bytes, p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
bool os::guard_memory(char* addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
  return linux_mprotect(addr, size, PROT_NONE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
bool os::unguard_memory(char* addr, size_t size) {
1664
fc9ed50498fb 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 1615
diff changeset
  3168
  return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3171
bool os::Linux::transparent_huge_pages_sanity_check(bool warn, size_t page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3172
  bool result = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3173
  void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3174
                 MAP_ANONYMOUS|MAP_PRIVATE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3175
                 -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3176
  if (p != MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3177
    void *aligned_p = align_ptr_up(p, page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3178
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3179
    result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3180
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3181
    munmap(p, page_size * 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3182
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3183
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3184
  if (warn && !result) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3185
    warning("TransparentHugePages is not supported by the operating system.");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3186
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3187
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3188
  return result;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3189
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3190
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3191
bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3192
  bool result = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3193
  void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3194
                 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3195
                 -1, 0);
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3196
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3197
  if (p != MAP_FAILED) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3198
    // We don't know if this really is a huge page or not.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3199
    FILE *fp = fopen("/proc/self/maps", "r");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3200
    if (fp) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3201
      while (!feof(fp)) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3202
        char chars[257];
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3203
        long x = 0;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3204
        if (fgets(chars, sizeof(chars), fp)) {
9625
822a93889b58 7043564: compile warning and copyright fixes
iveresov
parents: 9419
diff changeset
  3205
          if (sscanf(chars, "%lx-%*x", &x) == 1
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3206
              && x == (long)p) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3207
            if (strstr (chars, "hugepage")) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3208
              result = true;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3209
              break;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3210
            }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3211
          }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3212
        }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3213
      }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3214
      fclose(fp);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3215
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3216
    munmap(p, page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3217
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3218
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3219
  if (warn && !result) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3220
    warning("HugeTLBFS is not supported by the operating system.");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3221
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3222
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3223
  return result;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3224
}
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3225
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3226
/*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3227
* Set the coredump_filter bits to include largepages in core dump (bit 6)
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3228
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3229
* From the coredump_filter documentation:
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3230
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3231
* - (bit 0) anonymous private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3232
* - (bit 1) anonymous shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3233
* - (bit 2) file-backed private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3234
* - (bit 3) file-backed shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3235
* - (bit 4) ELF header pages in file-backed private memory areas (it is
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3236
*           effective only if the bit 2 is cleared)
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3237
* - (bit 5) hugetlb private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3238
* - (bit 6) hugetlb shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3239
*/
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3240
static void set_coredump_filter(void) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3241
  FILE *f;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3242
  long cdm;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3243
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3244
  if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3245
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3246
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3247
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3248
  if (fscanf(f, "%lx", &cdm) != 1) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3249
    fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3250
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3251
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3252
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3253
  rewind(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3254
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3255
  if ((cdm & LARGEPAGES_BIT) == 0) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3256
    cdm |= LARGEPAGES_BIT;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3257
    fprintf(f, "%#lx", cdm);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3258
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3259
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3260
  fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3261
}
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3262
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
// Large page support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
static size_t _large_page_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3267
size_t os::Linux::find_large_page_size() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3268
  size_t large_page_size = 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3269
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3270
  // large_page_size on Linux is used to round up heap size. x86 uses either
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3271
  // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3272
  // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3273
  // page as large as 256M.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3274
  //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3275
  // Here we try to figure out page size by parsing /proc/meminfo and looking
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3276
  // for a line with the following format:
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3277
  //    Hugepagesize:     2048 kB
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3278
  //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3279
  // If we can't determine the value (e.g. /proc is not mounted, or the text
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3280
  // format has been changed), we'll use the largest page size supported by
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3281
  // the processor.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3283
#ifndef ZERO
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3284
  large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3285
                     ARM_ONLY(2 * M) PPC_ONLY(4 * M);
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3286
#endif // ZERO
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3288
  FILE *fp = fopen("/proc/meminfo", "r");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3289
  if (fp) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3290
    while (!feof(fp)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3291
      int x = 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3292
      char buf[16];
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3293
      if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3294
        if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3295
          large_page_size = x * K;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3296
          break;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3297
        }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3298
      } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3299
        // skip to next line
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3300
        for (;;) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3301
          int ch = fgetc(fp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3302
          if (ch == EOF || ch == (int)'\n') break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3306
    fclose(fp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3307
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3308
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3309
  if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3310
    warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is "
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3311
        SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size),
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3312
        proper_unit_for_byte_size(large_page_size));
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3313
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3314
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3315
  return large_page_size;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3316
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3317
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3318
size_t os::Linux::setup_large_page_size() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3319
  _large_page_size = Linux::find_large_page_size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  const size_t default_page_size = (size_t)Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  if (_large_page_size > default_page_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
    _page_sizes[0] = _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
    _page_sizes[1] = default_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
    _page_sizes[2] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3326
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3327
  return _large_page_size;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3328
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3329
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3330
bool os::Linux::setup_large_page_type(size_t page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3331
  if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3332
      FLAG_IS_DEFAULT(UseSHM) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3333
      FLAG_IS_DEFAULT(UseTransparentHugePages)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3334
    // If UseLargePages is specified on the command line try all methods,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3335
    // if it's default, then try only UseTransparentHugePages.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3336
    if (FLAG_IS_DEFAULT(UseLargePages)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3337
      UseTransparentHugePages = true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3338
    } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3339
      UseHugeTLBFS = UseTransparentHugePages = UseSHM = true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3340
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3341
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3342
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3343
  if (UseTransparentHugePages) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3344
    bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3345
    if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3346
      UseHugeTLBFS = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3347
      UseSHM = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3348
      return true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3349
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3350
    UseTransparentHugePages = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3351
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3352
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3353
  if (UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3354
    bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3355
    if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3356
      UseSHM = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3357
      return true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3358
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3359
    UseHugeTLBFS = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3360
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3361
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3362
  return UseSHM;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3363
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3364
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3365
void os::large_page_init() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3366
  if (!UseLargePages) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3367
    UseHugeTLBFS = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3368
    UseTransparentHugePages = false;
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3369
    UseSHM = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3370
    return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3371
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3372
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3373
  size_t large_page_size = Linux::setup_large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3374
  UseLargePages          = Linux::setup_large_page_type(large_page_size);
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3375
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3376
  set_coredump_filter();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
#ifndef SHM_HUGETLB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
#define SHM_HUGETLB 04000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3383
char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) {
2268
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3384
  // "exec" is passed in but not used.  Creating the shared image for
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3385
  // the code cache doesn't have an SHM_X executable permission to check.
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3386
  assert(UseLargePages && UseSHM, "only for SHM large pages");
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3387
  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3388
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3389
  if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3390
    return NULL; // Fallback to small pages.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3391
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
  key_t key = IPC_PRIVATE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
  char *addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
  bool warn_on_failure = UseLargePages &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
                        (!FLAG_IS_DEFAULT(UseLargePages) ||
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3398
                         !FLAG_IS_DEFAULT(UseSHM) ||
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
                         !FLAG_IS_DEFAULT(LargePageSizeInBytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
                        );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  char msg[128];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
  // Create a large shared memory region to attach to based on size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
  // Currently, size is the total size of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
  int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  if (shmid == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
     // Possible reasons for shmget failure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
     // 1. shmmax is too small for Java heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
     //    > check shmmax value: cat /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
     //    > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
     // 2. not enough large page memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
     //    > check available large pages: cat /proc/meminfo
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
     //    > increase amount of large pages:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
     //          echo new_value > /proc/sys/vm/nr_hugepages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
     //      Note 1: different Linux may use different name for this property,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
     //            e.g. on Redhat AS-3 it is "hugetlb_pool".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
     //      Note 2: it's possible there's enough physical memory available but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
     //            they are so fragmented after a long run that they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
     //            coalesce into large pages. Try to reserve large pages when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
     //            the system is still "fresh".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
       jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
  // attach to the region
5532
34c4ef11dbed 6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents: 5413
diff changeset
  3429
  addr = (char*)shmat(shmid, req_addr, 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
  int err = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
  // Remove shmid. If shmat() is successful, the actual shared memory segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
  // will be deleted when it's detached by shmdt() or when the process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
  // terminates. If shmat() is not successful this will remove the shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
  // segment immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  shmctl(shmid, IPC_RMID, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  if ((intptr_t)addr == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3446
  return addr;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3447
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3448
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3449
static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3450
  assert(error == ENOMEM, "Only expect to fail if no memory is available");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3451
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3452
  bool warn_on_failure = UseLargePages &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3453
      (!FLAG_IS_DEFAULT(UseLargePages) ||
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3454
       !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3455
       !FLAG_IS_DEFAULT(LargePageSizeInBytes));
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3456
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3457
  if (warn_on_failure) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3458
    char msg[128];
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3459
    jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3460
        PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3461
    warning(msg);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3462
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3463
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3464
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3465
char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3466
  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3467
  assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3468
  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3469
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3470
  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3471
  char* addr = (char*)::mmap(req_addr, bytes, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3472
                             MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3473
                             -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3474
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3475
  if (addr == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3476
    warn_on_large_pages_failure(req_addr, bytes, errno);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3477
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3478
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3479
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3480
  assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3481
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
  return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3485
char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3486
  size_t large_page_size = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3487
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3488
  assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3489
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3490
  // Allocate small pages.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3491
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3492
  char* start;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3493
  if (req_addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3494
    assert(is_ptr_aligned(req_addr, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3495
    assert(is_size_aligned(bytes, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3496
    start = os::reserve_memory(bytes, req_addr);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3497
    assert(start == NULL || start == req_addr, "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3498
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3499
    start = os::reserve_memory_aligned(bytes, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3500
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3501
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3502
  if (start == NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3503
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3504
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3505
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3506
  assert(is_ptr_aligned(start, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3507
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3508
  // os::reserve_memory_special will record this memory area.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3509
  // Need to release it here to prevent overlapping reservations.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3510
  MemTracker::record_virtual_memory_release((address)start, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3511
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3512
  char* end = start + bytes;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3513
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3514
  // Find the regions of the allocated chunk that can be promoted to large pages.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3515
  char* lp_start = (char*)align_ptr_up(start, large_page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3516
  char* lp_end   = (char*)align_ptr_down(end, large_page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3517
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3518
  size_t lp_bytes = lp_end - lp_start;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3519
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3520
  assert(is_size_aligned(lp_bytes, large_page_size), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3521
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3522
  if (lp_bytes == 0) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3523
    // The mapped region doesn't even span the start and the end of a large page.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3524
    // Fall back to allocate a non-special area.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3525
    ::munmap(start, end - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3526
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3527
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3528
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3529
  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3530
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3531
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3532
  void* result;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3533
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3534
  if (start != lp_start) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3535
    result = ::mmap(start, lp_start - start, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3536
                    MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3537
                    -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3538
    if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3539
      ::munmap(lp_start, end - lp_start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3540
      return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3541
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3542
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3543
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3544
  result = ::mmap(lp_start, lp_bytes, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3545
                  MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3546
                  -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3547
  if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3548
    warn_on_large_pages_failure(req_addr, bytes, errno);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3549
    // If the mmap above fails, the large pages region will be unmapped and we
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3550
    // have regions before and after with small pages. Release these regions.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3551
    //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3552
    // |  mapped  |  unmapped  |  mapped  |
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3553
    // ^          ^            ^          ^
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3554
    // start      lp_start     lp_end     end
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3555
    //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3556
    ::munmap(start, lp_start - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3557
    ::munmap(lp_end, end - lp_end);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3558
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3559
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3560
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3561
  if (lp_end != end) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3562
      result = ::mmap(lp_end, end - lp_end, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3563
                      MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3564
                      -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3565
    if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3566
      ::munmap(start, lp_end - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3567
      return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3568
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3569
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3570
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3571
  return start;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3572
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3573
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3574
char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3575
  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3576
  assert(is_ptr_aligned(req_addr, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3577
  assert(is_power_of_2(alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3578
  assert(is_power_of_2(os::large_page_size()), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3579
  assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3580
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3581
  if (is_size_aligned(bytes, os::large_page_size()) && alignment <= os::large_page_size()) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3582
    return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3583
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3584
    return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3585
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3586
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3587
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3588
char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3589
  assert(UseLargePages, "only for large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3590
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3591
  char* addr;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3592
  if (UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3593
    addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3594
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3595
    assert(UseHugeTLBFS, "must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3596
    addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3597
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3598
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3599
  if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3600
    if (UseNUMAInterleaving) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3601
      numa_make_global(addr, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3602
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3603
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3604
    // The memory is committed
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3605
    MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3606
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3607
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3608
  return addr;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3609
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3610
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3611
bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3612
  // detaching the SHM segment will also delete it, see reserve_memory_special_shm()
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3613
  return shmdt(base) == 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3614
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3615
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3616
bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3617
  return pd_release_memory(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3618
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3619
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
bool os::release_memory_special(char* base, size_t bytes) {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3621
  assert(UseLargePages, "only for large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3622
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3623
  MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3624
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3625
  bool res;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3626
  if (UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3627
    res = os::Linux::release_memory_special_shm(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3628
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3629
    assert(UseHugeTLBFS, "must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3630
    res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3631
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3632
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3633
  if (res) {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3634
    tkr.record((address)base, bytes);
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3635
  } else {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3636
    tkr.discard();
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3637
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3638
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3639
  return res;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
size_t os::large_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
  return _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3646
// With SysV SHM the entire memory region must be allocated as shared
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3647
// memory.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3648
// HugeTLBFS allows application to commit large page memory on demand.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3649
// However, when committing memory with HugeTLBFS fails, the region
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3650
// that was supposed to be committed will lose the old reservation
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3651
// and allow other threads to steal that memory region. Because of this
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3652
// behavior we can't commit HugeTLBFS memory.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
bool os::can_commit_large_page_memory() {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3654
  return UseTransparentHugePages;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3657
bool os::can_execute_large_page_memory() {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3658
  return UseTransparentHugePages || UseHugeTLBFS;
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3659
}
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3660
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
// Reserve memory at an arbitrary address, only if that area is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
// available (and not reserved for something else).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3664
char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  const int max_tries = 10;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  char* base[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
  size_t size[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
  const size_t gap = 0x000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
  // Assert only that the size is a multiple of the page size, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
  // that's all that mmap requires, and since that's all we really know
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
  // about at this low abstraction level.  If we need higher alignment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
  // we can either pass an alignment to this method or verify alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  // in one of the methods further up the call chain.  See bug 5044738.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
  // Repeatedly allocate blocks until the block is allocated at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
  // right spot. Give up after max_tries. Note that reserve_memory() will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
  // automatically update _highest_vm_reserved_address if the call is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
  // successful. The variable tracks the highest memory address every reserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
  // by JVM. It is used to detect heap-stack collision if running with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
  // fixed-stack LinuxThreads. Because here we may attempt to reserve more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  // space than needed, it could confuse the collision detecting code. To
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
  // solve the problem, save current _highest_vm_reserved_address and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  // calculate the correct value before return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
  address old_highest = _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
  // Linux mmap allows caller to pass an address as hint; give it a try first,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
  // if kernel honors the hint then we can return immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
  char * addr = anon_mmap(requested_addr, bytes, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
  if (addr == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
     return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
     // mmap() is successful but it fails to reserve at the requested address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
     anon_munmap(addr, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
  for (i = 0; i < max_tries; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
    base[i] = reserve_memory(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
    if (base[i] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
      // Is this the block we wanted?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
      if (base[i] == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
        size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
      // Does this overlap the block we wanted? Give back the overlapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
      // parts and try again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
      size_t top_overlap = requested_addr + (bytes + gap) - base[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
      if (top_overlap >= 0 && top_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
        unmap_memory(base[i], top_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
        base[i] += top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
        size[i] = bytes - top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
        size_t bottom_overlap = base[i] + bytes - requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
        if (bottom_overlap >= 0 && bottom_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
          unmap_memory(requested_addr, bottom_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
          size[i] = bytes - bottom_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
          size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
  // Give back the unused reserved pieces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
  for (int j = 0; j < i; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
    if (base[j] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
      unmap_memory(base[j], size[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
  if (i < max_tries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
    _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
    return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
    _highest_vm_reserved_address = old_highest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
size_t os::read(int fd, void *buf, unsigned int nBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
  return ::read(fd, buf, nBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
// TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
// Solaris uses poll(), linux uses park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
// Poll() is likely a better choice, assuming that Thread.interrupt()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
// SIGSEGV, see 4355769.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
  assert(thread == Thread::current(),  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
  ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
  slp->reset() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
  OrderAccess::fence() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  if (interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
      if (os::is_interrupted(thread, true)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
        return OS_INTRPT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3780
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
      if(millis <= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
        return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
        assert(thread->is_Java_thread(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
        JavaThread *jt = (JavaThread *) thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
        ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
        OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
        jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
        // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
        // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
        slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
        // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
        jt->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
      // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
      // the 1st iteration ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3819
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
      if(millis <= 0) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
      slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
    return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
int os::naked_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
  // %% make the sleep time an integer flag. for now use 1 millisec.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
  return os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
// Sleep forever; naked call to OS-specific sleep; use with CAUTION
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
void os::infinite_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
  while (true) {    // sleep forever ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
    ::sleep(100);   // ... 100 seconds at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
// Used to convert frequent JVM_Yield() to nops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
bool os::dont_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
  return DontYieldALot;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
void os::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
void os::yield_all(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
  // Yields to all threads, including threads with lower priorities
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
  // Threads on Linux are all with same priority. The Solaris style
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
  // os::yield_all() with nanosleep(1ms) is not necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3861
// Called from the tight loops to possibly influence time-sharing heuristics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
void os::loop_breaker(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
  os::yield_all(attempts);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
// thread priority support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
// Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
// only supports dynamic priority, static priority must be zero. For real-time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
// applications, Linux supports SCHED_RR which allows static priority (1-99).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
// However, for large multi-threaded applications, SCHED_RR is not only slower
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
// of 5 runs - Sep 2005).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
// The following code actually changes the niceness of kernel-thread/LWP. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
// has an assumption that setpriority() only modifies one kernel-thread/LWP,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
// not the entire user process, and user level threads are 1:1 mapped to kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
// threads. It has always been the case, but could change in the future. For
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3883
int os::java_to_os_priority[CriticalPriority + 1] = {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
  19,              // 0 Entry should never be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
   4,              // 1 MinPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
   3,              // 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
   2,              // 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
   1,              // 4
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3891
   0,              // 5 NormPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
  -1,              // 6
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3893
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
  -2,              // 7
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
  -3,              // 8
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3896
  -4,              // 9 NearMaxPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3898
  -5,              // 10 MaxPriority
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3899
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3900
  -5               // 11 CriticalPriority
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3902
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
static int prio_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
  if (ThreadPriorityPolicy == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3905
    // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
    // if effective uid is not root. Perhaps, a more elegant way of doing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3907
    // this is to test CAP_SYS_NICE capability, but that will require libcap.so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3908
    if (geteuid() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3909
      if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3910
        warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3911
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3912
      ThreadPriorityPolicy = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3913
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
  }
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3915
  if (UseCriticalJavaThreadPriority) {
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3916
    os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3917
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3918
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
OSReturn os::set_native_priority(Thread* thread, int newpri) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
  int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
  return (ret == 0) ? OS_OK : OS_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
    *priority_ptr = java_to_os_priority[NormPriority];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
    return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
  errno = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
  *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
  return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
// Hint to the underlying OS that a task switch would not be good.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
// Void return because it's a hint and can fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3941
void os::hint_no_preempt() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3942
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
// suspend/resume support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
//  the low-level signal-based suspend/resume support is a remnant from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
//  old VM-suspension that used to be for java-suspension, safepoints etc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
//  within hotspot. Now there is a single use-case for this:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
//    - calling get_thread_pc() on the VMThread by the flat-profiler task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
//      that runs in the watcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
//  The remaining code is greatly simplified from the more general suspension
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
//  code that used to be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
//  The protocol is quite simple:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
//  - suspend:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
//      - sends a signal to the target thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
//      - polls the suspend state of the osthread using a yield loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3958
//      - target thread signal handler (SR_handler) sets suspend state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3959
//        and blocks in sigsuspend until continued
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
//  - resume:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
//      - sets target osthread state to continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
//      - sends signal to end the sigsuspend loop in the SR_handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
//  Note that the SR_lock plays no role in this suspend/resume protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
static void resume_clear_context(OSThread *osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
  osthread->set_ucontext(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
  osthread->set_siginfo(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
  osthread->set_ucontext(context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3974
  osthread->set_siginfo(siginfo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3975
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
// Handler function invoked when a thread's execution is suspended or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
// resumed. We have to be careful that only async-safe functions are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
// called here (Note: most pthread functions are not async safe and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
// should be avoided.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
// Note: sigwait() is a more natural fit than sigsuspend() from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
// interface point of view, but sigwait() prevents the signal hander
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
// from being run. libpthread would get very confused by not having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
// its signal handlers run and prevents sigwait()'s use with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
// mutex granting granting signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
//
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3989
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
  // Save and restore errno to avoid confusing native code with EINTR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
  // after sigsuspend.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
  int old_errno = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3996
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3997
  OSThread* osthread = thread->osthread();
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3998
  assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3999
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4000
  os::SuspendResume::State current = osthread->sr.state();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4001
  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4002
    suspend_save_context(osthread, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4003
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4004
    // attempt to switch the state, we assume we had a SUSPEND_REQUEST
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4005
    os::SuspendResume::State state = osthread->sr.suspended();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4006
    if (state == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4007
      sigset_t suspend_set;  // signals for sigsuspend()
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4008
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4009
      // get current set of blocked signals and unblock resume signal
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4010
      pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4011
      sigdelset(&suspend_set, SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4012
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4013
      sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4014
      // wait here until we are resumed
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4015
      while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4016
        sigsuspend(&suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4017
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4018
        os::SuspendResume::State result = osthread->sr.running();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4019
        if (result == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4020
          sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4021
          break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4022
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4023
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4024
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4025
    } else if (state == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4026
      // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4027
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4028
      ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4029
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
    resume_clear_context(osthread);
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4032
  } else if (current == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4033
    // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4034
  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4035
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
  } else {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4037
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
  errno = old_errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
static int SR_initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
  /* Get signal number to use for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
  if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
    int sig = ::strtol(s, 0, 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
    if (sig > 0 || sig < _NSIG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
        SR_signum = sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
  assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
        "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
  sigemptyset(&SR_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4059
  sigaddset(&SR_sigset, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4060
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
  /* Set up signal handler for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4062
  act.sa_flags = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4063
  act.sa_handler = (void (*)(int)) SR_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4065
  // SR_signum is blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4066
  // 4528190 - We also need to block pthread restart signal (32 on all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
  // supported Linux platforms). Note that LinuxThreads need to block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
  // this signal for all threads to work properly. So we don't have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
  // to use hard-coded signal number when setting up the mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
  pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
  if (sigaction(SR_signum, &act, 0) == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
  // Save signal flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
  os::Linux::set_our_sigflags(SR_signum, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4081
static int sr_notify(OSThread* osthread) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4082
  int status = pthread_kill(osthread->pthread_id(), SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4083
  assert_status(status == 0, status, "pthread_kill");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4084
  return status;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4085
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4086
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4087
// "Randomly" selected value for how long we want to spin
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4088
// before bailing out on suspending a thread, also how often
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4089
// we send a signal to a thread we want to resume
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4090
static const int RANDOMLY_LARGE_INTEGER = 1000000;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4091
static const int RANDOMLY_LARGE_INTEGER2 = 100;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
// returns true on success and false on error - really an error is fatal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
// but this seems the normal response to library errors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
static bool do_suspend(OSThread* osthread) {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4096
  assert(osthread->sr.is_running(), "thread should be running");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4097
  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4098
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
  // mark as suspended and send signal
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4100
  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4101
    // failed to switch, state wasn't running?
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4102
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4103
    return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4104
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4105
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4106
  if (sr_notify(osthread) != 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4107
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4108
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4109
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4110
  // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4111
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4112
    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4113
      break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4114
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4115
      // timeout
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4116
      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4117
      if (cancelled == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4118
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4119
      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4120
        // make sure that we consume the signal on the semaphore as well
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4121
        sr_semaphore.wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4122
        break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4123
      } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4124
        ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4125
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4126
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
    }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4128
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4129
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4130
  guarantee(osthread->sr.is_suspended(), "Must be suspended");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4131
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
static void do_resume(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
  assert(osthread->sr.is_suspended(), "thread should be suspended");
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4136
  assert(!sr_semaphore.trywait(), "invalid semaphore state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4137
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4138
  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4139
    // failed to switch to WAKEUP_REQUEST
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4140
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4141
    return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4142
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4143
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4144
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4145
    if (sr_notify(osthread) == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4146
      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4147
        if (osthread->sr.is_running()) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4148
          return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4149
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4150
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4151
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4152
      ShouldNotReachHere();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
  }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4155
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4156
  guarantee(osthread->sr.is_running(), "Must be running!");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
// interrupt support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
void os::interrupt(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4163
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4166
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4168
  if (!osthread->interrupted()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
    osthread->set_interrupted(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
    // More than one thread can get here with the same value of osthread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
    // resulting in multiple notifications.  We do, however, want the store
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
    // to interrupted() to be visible to other threads before we execute unpark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
    OrderAccess::fence();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
    ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
    if (slp != NULL) slp->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
  // For JSR166. Unpark even if interrupt status already was set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
  if (thread->is_Java_thread())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
    ((JavaThread*)thread)->parker()->unpark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
  ParkEvent * ev = thread->_ParkEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
  if (ev != NULL) ev->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4184
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4185
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
  bool interrupted = osthread->interrupted();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4194
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
  if (interrupted && clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
    osthread->set_interrupted(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
    // consider thread->_SleepEvent->reset() ... optional optimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
  return interrupted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
///////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
// signal handling (except suspend/resume)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
// This routine may be used by user applications as a "hook" to catch signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
// The user-defined signal handler must pass unrecognized signals to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
// routine, and if it returns true (non-zero), then the signal handler must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
// return immediately.  If the flag "abort_if_unrecognized" is true, then this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
// routine will never retun false (zero), but instead will execute a VM panic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
// routine kill the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
// If this routine returns false, it is OK to call it again.  This allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
// the user-defined signal handler to perform checks either before or after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4215
// the VM performs its own checks.  Naturally, the user code would be making
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
// a serious error if it tried to handle an exception (such as a null check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
// or breakpoint) that the VM was generating for its own correct operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
// This routine may recognize any of the following kinds of signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
//    SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4221
// It should be consulted by handlers for any of those signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
// The caller of this routine must pass in the three arguments supplied
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
// to the function referred to in the "sa_sigaction" (not the "sa_handler")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
// field of the structure passed to sigaction().  This routine assumes that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
// Note that the VM will print warnings if it detects conflicting signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
//
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  4231
extern "C" JNIEXPORT int
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
                        void* ucontext, int abort_if_unrecognized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
void signalHandler(int sig, siginfo_t* info, void* uc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
  assert(info != NULL && uc != NULL, "it must be old kernel");
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4237
  int orig_errno = errno;  // Preserve errno value over signal handler.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
  JVM_handle_linux_signal(sig, info, uc, true);
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4239
  errno = orig_errno;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
// This boolean allows users to forward their own non-matching signals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
// to JVM_handle_linux_signal, harmlessly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
bool os::Linux::signal_handlers_are_installed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
// For signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
struct sigaction os::Linux::sigact[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
unsigned int os::Linux::sigs = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
bool os::Linux::libjsig_is_loaded = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
typedef struct sigaction *(*get_signal_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
get_signal_t os::Linux::get_signal_action = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4254
struct sigaction* os::Linux::get_chained_signal_action(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
  struct sigaction *actp = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
  if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
    // Retrieve the old signal handler from libjsig
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
    actp = (*get_signal_action)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
  if (actp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
    // Retrieve the preinstalled signal handler from jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
    actp = get_preinstalled_handler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
  return actp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
static bool call_chained_handler(struct sigaction *actp, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
                                 siginfo_t *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
  // Call the old signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
  if (actp->sa_handler == SIG_DFL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
    // It's more reasonable to let jvm treat it as an unexpected exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
    // instead of taking the default action.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
  } else if (actp->sa_handler != SIG_IGN) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
    if ((actp->sa_flags & SA_NODEFER) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
      // automaticlly block the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
      sigaddset(&(actp->sa_mask), sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
    sa_handler_t hand;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
    sa_sigaction_t sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
    bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
    // retrieve the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
      sa = actp->sa_sigaction;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
      hand = actp->sa_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
    if ((actp->sa_flags & SA_RESETHAND) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
      actp->sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
    // try to honor the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
    sigset_t oset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
    pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    // call into the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
      (*sa)(sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
      (*hand)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
    // restore the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
    pthread_sigmask(SIG_SETMASK, &oset, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
  // Tell jvm's signal handler the signal is taken care of.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
  bool chained = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
  // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
  if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
    struct sigaction *actp = get_chained_signal_action(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
    if (actp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
      chained = call_chained_handler(actp, sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
  return chained;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
  if ((( (unsigned int)1 << sig ) & sigs) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
    return &sigact[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
  sigact[sig] = oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
  sigs |= (unsigned int)1 << sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
// for diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
int os::Linux::sigflags[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
int os::Linux::get_our_sigflags(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
  return sigflags[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
void os::Linux::set_our_sigflags(int sig, int flags) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
  sigflags[sig] = flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
void os::Linux::set_signal_handler(int sig, bool set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
  // Check for overwrite.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
  struct sigaction oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
  sigaction(sig, (struct sigaction*)NULL, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
  void* oldhand = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
                ? CAST_FROM_FN_PTR(void*,  oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
                : CAST_FROM_FN_PTR(void*,  oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
  if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
      oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
      oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
    if (AllowUserSignalHandlers || !set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
      // Do not overwrite; user takes responsibility to forward to us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
    } else if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
      // save the old handler in jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
      save_preinstalled_handler(sig, oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
      // libjsig also interposes the sigaction() call below and saves the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
      // old sigaction on it own.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
    } else {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4372
      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4373
                    "%#lx for signal %d.", (long)oldhand, sig));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
  struct sigaction sigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
  sigAct.sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
  if (!set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
    sigAct.sa_sigaction = signalHandler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  // Save flags, which are set by ours
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
  sigflags[sig] = sigAct.sa_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
  int ret = sigaction(sig, &sigAct, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
  assert(ret == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
  void* oldhand2  = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
                  ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
                  : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
  assert(oldhand2 == oldhand, "no concurrent signal handler installation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
// install signal handlers for signals that HotSpot needs to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
// handle in order to support Java-level exception handling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
void os::Linux::install_signal_handlers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
  if (!signal_handlers_are_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
    signal_handlers_are_installed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
    // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
    typedef void (*signal_setting_t)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
    signal_setting_t begin_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
    signal_setting_t end_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
    begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
                             dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
    if (begin_signal_setting != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
      end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
                             dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
      get_signal_action = CAST_TO_FN_PTR(get_signal_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
                            dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
      libjsig_is_loaded = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
      assert(UseSignalChaining, "should enable signal-chaining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
      // Tell libjsig jvm is setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
      (*begin_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
    set_signal_handler(SIGSEGV, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
    set_signal_handler(SIGPIPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
    set_signal_handler(SIGBUS, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
    set_signal_handler(SIGILL, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
    set_signal_handler(SIGFPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
    set_signal_handler(SIGXFSZ, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
      // Tell libjsig jvm finishes setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
      (*end_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
    // We don't activate signal checker if libjsig is in place, we trust ourselves
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4438
    // and if UserSignalHandler is installed all bets are off.
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4439
    // Log that signal checking is off only if -verbose:jni is specified.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
    if (CheckJNICalls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
      if (libjsig_is_loaded) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4442
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4443
          tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4444
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
      if (AllowUserSignalHandlers) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4448
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4449
          tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4450
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
// This is the fastest way to get thread cpu time on Linux.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
// Returns cpu time (user+sys) for any thread, not only for current.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
// POSIX compliant clocks are implemented in the kernels 2.6.16+.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
// It might work on 2.6.10+ with a special kernel/glibc patch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
// For reference, please, see IEEE Std 1003.1-2004:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
//   http://www.unix.org/single_unix_specification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
  int rc = os::Linux::clock_gettime(clockid, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
  assert(rc == 0, "clock_gettime is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  4469
  return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
/////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
// glibc on Linux platform uses non-documented flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
// to indicate, that some special sort of signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
// trampoline is used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
// We will never set this flag, and we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
// ignore this flag in our diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
#ifdef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
#undef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4480
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
#define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4483
static const char* get_signal_handler_name(address handler,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4484
                                           char* buf, int buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4485
  int offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4486
  bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
  if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
    // skip directory names
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
    const char *p1, *p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4490
    p1 = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4491
    size_t len = strlen(os::file_separator());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4492
    while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
    jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
    jio_snprintf(buf, buflen, PTR_FORMAT, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
                                 char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
  struct sigaction sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
  sigaction(sig, NULL, &sa);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
  // See comment for SIGNIFICANT_SIGNAL_MASK define
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
  sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4508
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
  st->print("%s: ", os::exception_name(sig, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
  address handler = (sa.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
    ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
    : CAST_FROM_FN_PTR(address, sa.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
  if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
    st->print("SIG_DFL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
  } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
    st->print("SIG_IGN");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
    st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
  st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
  address rh = VMError::get_resetted_sighandler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
  // May be, handler was resetted by VMError?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
  if(rh != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
    handler = rh;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
    sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
  st->print(", sa_flags="   PTR32_FORMAT, sa.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
  // Check: is it our handler?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
  if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
     handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
    // It is our signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
    // check for flags, reset system-used one!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
    if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
      st->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
                ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
                os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4547
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
#define DO_SIGNAL_CHECK(sig) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  if (!sigismember(&check_signal_done, sig)) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
    os::Linux::check_signal_handler(sig)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
// This method is a periodic task to check for misbehaving JNI applications
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
// under CheckJNI, we can add any periodic checks here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
void os::run_periodic_checks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
  if (check_signals == false) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
  // SEGV and BUS if overridden could potentially prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
  // generation of hs*.log in the event of a crash, debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
  // such a case can be very challenging, so we absolutely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
  // check the following for a good measure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
  DO_SIGNAL_CHECK(SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
  DO_SIGNAL_CHECK(SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
  DO_SIGNAL_CHECK(SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
  DO_SIGNAL_CHECK(SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
  DO_SIGNAL_CHECK(SIGPIPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
  DO_SIGNAL_CHECK(SIGXFSZ);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
  // ReduceSignalUsage allows the user to override these handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
  // see comments at the very top and jvm_solaris.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
    DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
    DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
    DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
    DO_SIGNAL_CHECK(BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
  DO_SIGNAL_CHECK(SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
static os_sigaction_t os_sigaction = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
void os::Linux::check_signal_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
  char buf[O_BUFLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
  address jvmHandler = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
  if (os_sigaction == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
    // only trust the default sigaction, in case it has been interposed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
    os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4598
    if (os_sigaction == NULL) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4599
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4600
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4601
  os_sigaction(sig, (struct sigaction*)NULL, &act);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4602
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
  act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
  address thisHandler = (act.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
    ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
    : CAST_FROM_FN_PTR(address, act.sa_handler) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
  switch(sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
  case SIGPIPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
  case SIGXFSZ:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
    jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
  case SHUTDOWN1_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
  case SHUTDOWN2_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
  case SHUTDOWN3_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
  case BREAK_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
    jvmHandler = (address)user_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
  case INTERRUPT_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
    if (sig == SR_signum) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4634
      jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
  if (thisHandler != jvmHandler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
    tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
    tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
    tty->print_cr("  found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
  } else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
    tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
    tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
    tty->print_cr("  found:" PTR32_FORMAT, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
  // Dump all the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4656
  if (sigismember(&check_signal_done, sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4657
    print_signal_handlers(tty, buf, O_BUFLEN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4658
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4659
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4661
extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4663
extern bool signal_name(int signo, char* buf, size_t len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
const char* os::exception_name(int exception_code, char* buf, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
  if (0 < exception_code && exception_code <= SIGRTMAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
    // signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
    if (!signal_name(exception_code, buf, size)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
      jio_snprintf(buf, size, "SIG%d", exception_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4671
    return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4674
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4675
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4677
// this is called _before_ the most of global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
void os::init(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
  char dummy;   /* used to get a guess on initial stack address */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
//  first_hrtime = gethrtime();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
  // With LinuxThreads the JavaMain thread pid (primordial thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
  // is different than the pid of the java launcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
  // So, on Linux, the launcher thread pid is passed to the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
  // via the sun.java.launcher.pid property.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
  // Use this property instead of getpid() if it was correctly passed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
  // See bug 6351349.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
  pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
  _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
  clock_tics_per_sec = sysconf(_SC_CLK_TCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
  init_random(1234567);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
  ThreadCritical::initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
  Linux::set_page_size(sysconf(_SC_PAGESIZE));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
  if (Linux::page_size() == -1) {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4700
    fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4701
                  strerror(errno)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
  init_page_sizes((size_t) Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
  Linux::initialize_system_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
  // main_thread points to the aboriginal thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
  Linux::_main_thread = pthread_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
  Linux::clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
  initial_time_count = os::elapsed_counter();
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  4712
  pthread_mutex_init(&dl_mutex, NULL);
17090
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4713
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4714
  // If the pagesize of the VM is greater than 8K determine the appropriate
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4715
  // number of initial guard pages.  The user can change this with the
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4716
  // command line arguments, if needed.
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4717
  if (vm_page_size() > (int)Linux::vm_default_page_size()) {
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4718
    StackYellowPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4719
    StackRedPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4720
    StackShadowPages = round_to((StackShadowPages*Linux::vm_default_page_size()), vm_page_size()) / vm_page_size();
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4721
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
// To install functions for atexit system call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
  static void perfMemory_exit_helper() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
    perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4731
// this is called _after_ the global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4732
jint os::init_2(void)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
  Linux::fast_thread_clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
  // Allocate a single page and mark it as readable for safepoint polling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
  address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
  guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4740
  os::set_polling_page( polling_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4742
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
  if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
  if (!UseMembar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
    address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  4749
    guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
    os::set_memory_serialize_page( mem_serialize_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
    if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4756
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
  // initialize suspend/resume support - must do this before signal_sets_init()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
  if (SR_initialize() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
    perror("SR_initialize failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
    return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4763
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
  Linux::signal_sets_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
  Linux::install_signal_handlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4766
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4767
  // Check minimum allowable stack size for thread creation and to initialize
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4768
  // the java system classes, including StackOverflowError - depends on page
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4769
  // size.  Add a page for compiler2 recursion in main thread.
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4770
  // Add in 2*BytesPerWord times page size to account for VM stack during
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4771
  // class initialization depending on 32 or 64 bit VM.
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4772
  os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
17090
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4773
            (size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() +
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4774
                    (2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size());
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4775
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4776
  size_t threadStackSizeInBytes = ThreadStackSize * K;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4777
  if (threadStackSizeInBytes != 0 &&
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4778
      threadStackSizeInBytes < os::Linux::min_stack_allowed) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4779
        tty->print_cr("\nThe stack size specified is too small, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4780
                      "Specify at least %dk",
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4781
                      os::Linux::min_stack_allowed/ K);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4782
        return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
  // Make the stack size a multiple of the page size so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4786
  // the yellow/red zones can be guarded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
        vm_page_size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
  Linux::capture_initial_stack(JavaThread::stack_size_at_create());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
  Linux::libpthread_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
  if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
     tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
          Linux::glibc_version(), Linux::libpthread_version(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
          Linux::is_floating_stack() ? "floating stack" : "fixed stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4799
  if (UseNUMA) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4800
    if (!Linux::libnuma_init()) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4801
      UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4802
    } else {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4803
      if ((Linux::numa_max_node() < 1)) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4804
        // There's only one node(they start from 0), disable NUMA.
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4805
        UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4806
      }
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4807
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4808
    // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4809
    // we can make the adaptive lgrp chunk resizing work. If the user specified
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4810
    // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4811
    // disable adaptive resizing.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4812
    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4813
      if (FLAG_IS_DEFAULT(UseNUMA)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4814
        UseNUMA = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4815
      } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4816
        if (FLAG_IS_DEFAULT(UseLargePages) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4817
            FLAG_IS_DEFAULT(UseSHM) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4818
            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4819
          UseLargePages = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4820
        } else {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4821
          warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4822
          UseAdaptiveSizePolicy = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4823
          UseAdaptiveNUMAChunkSizing = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4824
        }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4825
      }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4826
    }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4827
    if (!UseNUMA && ForceNUMA) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4828
      UseNUMA = true;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4829
    }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4830
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4831
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
  if (MaxFDLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
    // set the number of file descriptors to max. print out error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
    // if getrlimit/setrlimit fails but continue regardless.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
    struct rlimit nbr_files;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
    int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
    if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
      if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
        perror("os::init_2 getrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
      nbr_files.rlim_cur = nbr_files.rlim_max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
      if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
        if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
          perror("os::init_2 setrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
  // Initialize lock used to serialize thread creation (see os::create_thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
  Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
  // at-exit methods are called in the reverse order of their registration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
  // atexit functions are called on return from main or as a result of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
  // call to exit(3C). There can be only 32 of these functions registered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4856
  // and atexit() does not set errno.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
  if (PerfAllowAtExitRegistration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
    // only register atexit functions if PerfAllowAtExitRegistration is set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
    // atexit functions can be delayed until process exit time, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4861
    // can be problematic for embedded VM situations. Embedded VMs should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
    // call DestroyJavaVM() to assure that VM resources are released.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4864
    // note: perfMemory_exit_helper atexit function may be removed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
    // the future if the appropriate cleanup code can be added to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
    // VM_Exit VMOperation's doit method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
    if (atexit(perfMemory_exit_helper) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4868
      warning("os::init2 atexit(perfMemory_exit_helper) failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
  // initialize thread priority policy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
  prio_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4874
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4875
  return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4876
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4877
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4878
// this is called at the end of vm_initialization
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4879
void os::init_3(void)
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4880
{
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4881
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4882
  // Start the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4883
  if (LowMemoryProtection) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4884
    MemNotifyThread::start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4885
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4886
  return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4887
#endif
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4888
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4889
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4890
// Mark the polling page as unreadable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4891
void os::make_polling_page_unreadable(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4892
  if( !guard_memory((char*)_polling_page, Linux::page_size()) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4893
    fatal("Could not disable polling page");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
// Mark the polling page as readable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
void os::make_polling_page_readable(void) {
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4898
  if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
    fatal("Could not enable polling page");
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4900
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
int os::active_processor_count() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
  // Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
  // so just return the number of online processors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
  return online_cpus;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4911
void os::set_native_thread_name(const char *name) {
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4912
  // Not yet implemented.
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4913
  return;
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4914
}
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4915
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
bool os::distribute_processes(uint length, uint* distribution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4921
bool os::bind_to_processor(uint processor_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4924
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4926
///
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4928
void os::SuspendedThreadTask::internal_do_task() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4929
  if (do_suspend(_thread->osthread())) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4930
    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4931
    do_task(context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4932
    do_resume(_thread->osthread());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4933
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4934
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4935
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4936
class PcFetcher : public os::SuspendedThreadTask {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4937
public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4938
  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4939
  ExtendedPC result();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4940
protected:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4941
  void do_task(const os::SuspendedThreadTaskContext& context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4942
private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4943
  ExtendedPC _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4944
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4945
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4946
ExtendedPC PcFetcher::result() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4947
  guarantee(is_done(), "task is not done yet.");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4948
  return _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4949
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4950
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4951
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4952
  Thread* thread = context.thread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4953
  OSThread* osthread = thread->osthread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4954
  if (osthread->ucontext() != NULL) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4955
    _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4956
  } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4957
    // NULL context is unexpected, double-check this is the VMThread
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4958
    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4959
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4960
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4961
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4962
// Suspends the target using the signal mechanism and then grabs the PC before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
// resuming the target. Used by the flat-profiler only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
ExtendedPC os::get_thread_pc(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
  // Make sure that it is called by the watcher for the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
  assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
  assert(thread->is_VM_thread(), "Can only be called for VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4969
  PcFetcher fetcher(thread);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4970
  fetcher.run();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4971
  return fetcher.result();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4974
int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4975
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4976
   if (is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4977
      return pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
   } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
      // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
      // word back to default 64bit precision if condvar is signaled. Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
      // wants 53bit precision.  Save and restore current value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
      int fpu = get_fpu_control_word();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
      int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
      set_fpu_control_word(fpu);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4985
      return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4986
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4987
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4988
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4989
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4990
// debug support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4991
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4992
bool os::find(address addr, outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4993
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4994
  memset(&dlinfo, 0, sizeof(dlinfo));
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  4995
  if (dladdr(addr, &dlinfo) != 0) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4996
    st->print(PTR_FORMAT ": ", addr);
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  4997
    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4998
      st->print("%s+%#x", dlinfo.dli_sname,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4999
                 addr - (intptr_t)dlinfo.dli_saddr);
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5000
    } else if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5001
      st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5002
    } else {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5003
      st->print("<absolute address>");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5004
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5005
    if (dlinfo.dli_fname != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5006
      st->print(" in %s", dlinfo.dli_fname);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5007
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5008
    if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5009
      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5010
    }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5011
    st->cr();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5013
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5014
      // decode some bytes around the PC
16670
4af09aff4237 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 16669
diff changeset
  5015
      address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
4af09aff4237 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 16669
diff changeset
  5016
      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
      address       lowest = (address) dlinfo.dli_sname;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
      if (!lowest)  lowest = (address) dlinfo.dli_fbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
      if (begin < lowest)  begin = lowest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5020
      Dl_info dlinfo2;
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5021
      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
          && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
        end = (address) dlinfo2.dli_saddr;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5024
      Disassembler::decode(begin, end, st);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
// misc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
// This does not do anything on Linux. This is basically a hook for being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
// able to use structured exception handling (thread-local exception filters)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
// on, e.g., Win32.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5037
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
                         JavaCallArguments* args, Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
  f(value, method, args, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
void os::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
int os::message_box(const char* title, const char* message) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
  fdStream err(defaultStream::error_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
  err.print_raw_cr(title);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
  for (i = 0; i < 78; i++) err.print_raw("-");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
  err.print_raw_cr(message);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
  char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
  // Prevent process from exiting upon "read error" without consuming all CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
  while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
  return buf[0] == 'y' || buf[0] == 'Y';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
int os::stat(const char *path, struct stat *sbuf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
  char pathbuf[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
  if (strlen(path) > MAX_PATH - 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5068
    errno = ENAMETOOLONG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
  }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5071
  os::native_path(strcpy(pathbuf, path));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
  return ::stat(pathbuf, sbuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5075
bool os::check_heap(bool force) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
  return ::vsnprintf(buf, count, format, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5083
// Is a (classpath) directory empty?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
bool os::dir_is_empty(const char* path) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
  DIR *dir = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
  struct dirent *ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
  dir = opendir(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
  if (dir == NULL) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
  /* Scan the directory */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
  bool result = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
  char buf[sizeof(struct dirent) + MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
  while (result && (ptr = ::readdir(dir)) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
    if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
      result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
  closedir(dir);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5103
// This code originates from JDK's sysOpen and open64_w
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5104
// from src/solaris/hpi/src/system_md.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5105
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5106
#ifndef O_DELETE
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5107
#define O_DELETE 0x10000
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5108
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5109
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5110
// Open a file. Unlink the file immediately after open returns
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5111
// if the specified oflag has the O_DELETE flag set.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5112
// O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5113
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5114
int os::open(const char *path, int oflag, int mode) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5115
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5116
  if (strlen(path) > MAX_PATH - 1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5117
    errno = ENAMETOOLONG;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5118
    return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5119
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5120
  int fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5121
  int o_delete = (oflag & O_DELETE);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5122
  oflag = oflag & ~O_DELETE;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5123
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5124
  fd = ::open64(path, oflag, mode);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5125
  if (fd == -1) return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5126
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5127
  //If the open succeeded, the file might still be a directory
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5128
  {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5129
    struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5130
    int ret = ::fstat64(fd, &buf64);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5131
    int st_mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5132
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5133
    if (ret != -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5134
      if ((st_mode & S_IFMT) == S_IFDIR) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5135
        errno = EISDIR;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5136
        ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5137
        return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5138
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5139
    } else {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5140
      ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5141
      return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5142
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5143
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5144
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5145
    /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5146
     * All file descriptors that are opened in the JVM and not
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5147
     * specifically destined for a subprocess should have the
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5148
     * close-on-exec flag set.  If we don't set it, then careless 3rd
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5149
     * party native code might fork and exec without closing all
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5150
     * appropriate file descriptors (e.g. as we do in closeDescriptors in
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5151
     * UNIXProcess.c), and this in turn might:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5152
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5153
     * - cause end-of-file to fail to be detected on some file
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5154
     *   descriptors, resulting in mysterious hangs, or
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5155
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5156
     * - might cause an fopen in the subprocess to fail on a system
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5157
     *   suffering from bug 1085341.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5158
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5159
     * (Yes, the default setting of the close-on-exec flag is a Unix
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5160
     * design flaw)
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5161
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5162
     * See:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5163
     * 1085341: 32-bit stdio routines should support file descriptors >255
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5164
     * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5165
     * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5166
     */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5167
#ifdef FD_CLOEXEC
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5168
    {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5169
        int flags = ::fcntl(fd, F_GETFD);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5170
        if (flags != -1)
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5171
            ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5172
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5173
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5174
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5175
  if (o_delete != 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5176
    ::unlink(path);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5177
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5178
  return fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5179
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5180
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5181
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
// create binary file, rewriting existing file if required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
int os::create_binary_file(const char* path, bool rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
  int oflags = O_WRONLY | O_CREAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
  if (!rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
    oflags |= O_EXCL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
  return ::open64(path, oflags, S_IREAD | S_IWRITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
// return current position of file pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
jlong os::current_file_offset(int fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
  return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
// move file pointer to the specified offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
jlong os::seek_to_file_offset(int fd, jlong offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
  return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5199
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5201
// This code originates from JDK's sysAvailable
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5202
// from src/solaris/hpi/src/native_threads/src/sys_api_td.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5203
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5204
int os::available(int fd, jlong *bytes) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5205
  jlong cur, end;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5206
  int mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5207
  struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5208
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5209
  if (::fstat64(fd, &buf64) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5210
    mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5211
    if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5212
      /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5213
      * XXX: is the following call interruptible? If so, this might
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5214
      * need to go through the INTERRUPT_IO() wrapper as for other
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5215
      * blocking, interruptible calls in this file.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5216
      */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5217
      int n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5218
      if (::ioctl(fd, FIONREAD, &n) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5219
        *bytes = n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5220
        return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5221
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5222
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5223
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5224
  if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5225
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5226
  } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5227
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5228
  } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5229
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5230
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5231
  *bytes = end - cur;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5232
  return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5233
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5234
7458
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5235
int os::socket_available(int fd, jint *pbytes) {
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5236
  // Linux doc says EINTR not returned, unlike Solaris
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5237
  int ret = ::ioctl(fd, FIONREAD, pbytes);
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5238
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5239
  //%% note ioctl can return 0 when successful, JVM_SocketAvailable
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5240
  // is expected to return 0 on failure and 1 on success to the jdk.
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5241
  return (ret < 0) ? 0 : 1;
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5242
}
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5243
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
// Map a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5245
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
                     char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
                     bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
  int prot;
11967
ce179af268b1 7142641: -Xshared:on fails on ARM
dlong
parents: 11601
diff changeset
  5249
  int flags = MAP_PRIVATE;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
  if (read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
    prot = PROT_READ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
    prot = PROT_READ | PROT_WRITE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
  if (allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
    prot |= PROT_EXEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
  char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
                                     fd, file_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
  if (mapped_address == MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
  return mapped_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
// Remap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5275
char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5276
                       char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
                       bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
  // same as map_memory() on this OS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
                        allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
// Unmap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5285
bool os::pd_unmap_memory(char* addr, size_t bytes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
  return munmap(addr, bytes) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
static clockid_t thread_cpu_clockid(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
  pthread_t tid = thread->osthread()->pthread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
  // Get thread clockid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
  int rc = os::Linux::pthread_getcpuclockid(tid, &clockid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
  assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
  return clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
// are used by JVM M&M and JVMTI to get user+sys or user CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
// of a thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
// the fast estimate available on the platform.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
jlong os::current_thread_cpu_time() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
    // return user + sys since the cost is the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
    return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
jlong os::thread_cpu_time(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
  // consistent with what current_thread_cpu_time() returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
    return slow_thread_cpu_time(thread, true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
    return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
    return slow_thread_cpu_time(thread, user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
//  -1 on error.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
  static bool proc_task_unchecked = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
  static const char *proc_stat_path = "/proc/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
  pid_t  tid = thread->osthread()->thread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
  char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
  int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
  char proc_name[64];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
  int count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
  long sys_time, user_time;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5356
  char cdummy;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
  int idummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
  long ldummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
  FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
  // The /proc/<tid>/stat aggregates per-process usage on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
  // new Linux kernels 2.6+ where NPTL is supported.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
  // The /proc/self/task/<tid>/stat still has the per-thread usage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
  // See bug 6328462.
15794
af92b7196818 8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents: 15743
diff changeset
  5365
  // There possibly can be cases where there is no directory
af92b7196818 8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents: 15743
diff changeset
  5366
  // /proc/self/task, so we check its availability.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
  if (proc_task_unchecked && os::Linux::is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
    // This is executed only once
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
    proc_task_unchecked = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
    fp = fopen("/proc/self/task", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
    if (fp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
      proc_stat_path = "/proc/self/task/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
  sprintf(proc_name, proc_stat_path, tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
  fp = fopen(proc_name, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
  if ( fp == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
  statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
  stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
  fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
  // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
  // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
  // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
  //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
  // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
  // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
  s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
  if (s == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
  // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
  do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5396
  count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5397
                 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
                 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
                 &user_time, &sys_time);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5400
  if ( count != 13 ) return -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
  if (user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
    return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
    return (jlong)user_time * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5422
bool os::is_thread_cpu_time_supported() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5423
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
// System loadavg support.  Returns -1 if load average cannot be obtained.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5427
// Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5428
// so just return the system wide load average.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
int os::loadavg(double loadavg[], int nelem) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
  return ::getloadavg(loadavg, nelem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
void os::pause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
  char filename[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5435
  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
  if (fd != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
    struct stat buf;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5444
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
    while (::stat(filename, &buf) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
      (void)::poll(NULL, 0, 100);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5448
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5449
    jio_fprintf(stderr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
      "Could not open pause file '%s', continuing immediately.\n", filename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
// Refer to the comments in os_solaris.cpp park-unpark.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
// hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
// For specifics regarding the bug see GLIBC BUGID 261237 :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
//    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
// is used.  (The simple C test-case provided in the GLIBC bug report manifests the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
// hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
// and monitorenter when we're using 1-0 locking.  All those operations may result in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
// calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
// of libpthread avoids the problem, but isn't practical.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
// Possible remedies:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
// 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
//      This is palliative and probabilistic, however.  If the thread is preempted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
//      between the call to compute_abstime() and pthread_cond_timedwait(), more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
//      than the minimum period may have passed, and the abstime may be stale (in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
//      past) resultin in a hang.   Using this technique reduces the odds of a hang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
//      but the JVM is still vulnerable, particularly on heavily loaded systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
// 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
//      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
//      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
//      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
//      thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
// 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
//      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
//      a timeout request to the chron thread and then blocking via pthread_cond_wait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
//      This also works well.  In fact it avoids kernel-level scalability impediments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
//      on certain platforms that don't handle lots of active pthread_cond_timedwait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
//      timers in a graceful fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
// 4.   When the abstime value is in the past it appears that control returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
//      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
//      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
//      can avoid the problem by reinitializing the condvar -- by cond_destroy()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
//      followed by cond_init() -- after all calls to pthread_cond_timedwait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
//      It may be possible to avoid reinitialization by checking the return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
//      value from pthread_cond_timedwait().  In addition to reinitializing the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
//      condvar we must establish the invariant that cond_signal() is only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
//      within critical sections protected by the adjunct mutex.  This prevents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
//      cond_signal() from "seeing" a condvar that's in the midst of being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
//      reinitialized or that is corrupt.  Sadly, this invariant obviates the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
//      desirable signal-after-unlock optimization that avoids futile context switching.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
//      I'm also concerned that some versions of NTPL might allocate an auxilliary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
//      structure when a condvar is used or initialized.  cond_destroy()  would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5506
//      release the helper structure.  Our reinitialize-after-timedwait fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
//      put excessive stress on malloc/free and locks protecting the c-heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
// We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
// It may be possible to refine (4) by checking the kernel and NTPL verisons
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
// and only enabling the work-around for vulnerable environments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
// utility to compute the abstime argument to timedwait:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
// millis is the relative timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
// abstime will be the absolute timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
// TODO: replace compute_abstime() with unpackTime()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
  if (millis < 0)  millis = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
  struct timeval now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
  int status = gettimeofday(&now, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5522
  assert(status == 0, "gettimeofday");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5523
  jlong seconds = millis / 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
  millis %= 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
  if (seconds > 50000000) { // see man cond_timedwait(3T)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
    seconds = 50000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5528
  abstime->tv_sec = now.tv_sec  + seconds;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
  long       usec = now.tv_usec + millis * 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
  if (usec >= 1000000) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
    abstime->tv_sec += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
    usec -= 1000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
  abstime->tv_nsec = usec * 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
  return abstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
// Conceptually TryPark() should be equivalent to park(0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
int os::PlatformEvent::TryPark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
    const int v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5545
    guarantee ((v == 0) || (v == 1), "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
    if (Atomic::cmpxchg (0, &_Event, v) == v) return v  ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
void os::PlatformEvent::park() {       // AKA "down()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
  // Invariant: Only the thread associated with the Event/PlatformEvent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
  // may call park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
  // TODO: assert that _Assoc != NULL or _Assoc == Self
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
  if (v == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
     // Do this the hard way by blocking ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
     int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
     assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
     guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
     ++ _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
     while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
        status = pthread_cond_wait(_cond, _mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
        // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
        // Treat this the same as if the wait was interrupted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
        if (status == ETIME) { status = EINTR; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
        assert_status(status == 0 || status == EINTR, status, "cond_wait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
     -- _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
    _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
     status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
     assert_status(status == 0, status, "mutex_unlock");
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5578
    // Paranoia to ensure our locked and lock-free paths interact
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5579
    // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5580
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
  guarantee (_Event >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5585
int os::PlatformEvent::park(jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5586
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5587
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5588
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5589
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5590
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5591
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5592
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
  if (v != 0) return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
  // We do this the hard way, by blocking the thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
  // Consider enforcing a minimum timeout value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
  struct timespec abst;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
  compute_abstime(&abst, millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
  int ret = OS_TIMEOUT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
  int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
  assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
  ++_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
  // Object.wait(timo) will return because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
  // (a) notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5609
  // (b) timeout
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
  // (c) thread.interrupt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
  // Thread.interrupt and object.notify{All} both call Event::set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
  // That is, we treat thread.interrupt as a special case of notification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
  // The underlying Solaris implementation, cond_timedwait, admits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
  // spurious/premature wakeups, but the JLS/JVM spec prevents the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
  // JVM from making those visible to Java code.  As such, we must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
  // filter out spurious wakeups.  We assume all ETIME returns are valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5618
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
  // TODO: properly differentiate simultaneous notify+interrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
  // In that case, we should propagate the notify to another waiter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
  while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5623
    status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5624
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5625
      pthread_cond_destroy (_cond);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5626
      pthread_cond_init (_cond, NULL) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
    assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
                  status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
                  status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
    if (!FilterSpuriousWakeups) break ;                 // previous semantics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
    if (status == ETIME || status == ETIMEDOUT) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
    // We consume and ignore EINTR and spurious wakeups.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
  --_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
  if (_Event >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
     ret = OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
  _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
  status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
  assert_status(status == 0, status, "mutex_unlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
  assert (_nParked == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5643
  // Paranoia to ensure our locked and lock-free paths interact
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5644
  // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5645
  OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
  return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
void os::PlatformEvent::unpark() {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5650
  // Transitions for _Event:
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5651
  //    0 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5652
  //    1 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5653
  //   -1 :=> either 0 or 1; must signal target thread
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5654
  //          That is, we can safely transition _Event from -1 to either
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5655
  //          0 or 1. Forcing 1 is slightly more efficient for back-to-back
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5656
  //          unpark() calls.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5657
  // See also: "Semaphores in Plan 9" by Mullender & Cox
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5658
  //
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5659
  // Note: Forcing a transition from "-1" to "1" on an unpark() means
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5660
  // that it will take two back-to-back park() calls for the owning
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5661
  // thread to block. This has the benefit of forcing a spurious return
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5662
  // from the first park() call after an unpark() call which will help
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5663
  // shake out uses of park() and unpark() without condition variables.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5664
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5665
  if (Atomic::xchg(1, &_Event) >= 0) return;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5666
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5667
  // Wait for the thread associated with the event to vacate
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5668
  int status = pthread_mutex_lock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5669
  assert_status(status == 0, status, "mutex_lock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5670
  int AnyWaiters = _nParked;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5671
  assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5672
  if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5673
    AnyWaiters = 0;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5674
    pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5675
  }
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5676
  status = pthread_mutex_unlock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5677
  assert_status(status == 0, status, "mutex_unlock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5678
  if (AnyWaiters != 0) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5679
    status = pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5680
    assert_status(status == 0, status, "cond_signal");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5683
  // Note that we signal() _after dropping the lock for "immortal" Events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5684
  // This is safe and avoids a common class of  futile wakeups.  In rare
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5685
  // circumstances this can cause a thread to return prematurely from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5686
  // cond_{timed}wait() but the spurious wakeup is benign and the victim will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5687
  // simply re-test the condition and re-park itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5688
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
// JSR166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
// -------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
 * The solaris and linux implementations of park/unpark are fairly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
 * conservative for now, but can be improved. They currently use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
 * mutex/condvar pair, plus a a count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5698
 * Park decrements count if > 0, else does a condvar wait.  Unpark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
 * sets count to 1 and signals condvar.  Only one thread ever waits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
 * on the condvar. Contention seen when trying to park implies that someone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
 * is unparking you, so don't wait. And spurious returns are fine, so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
 * is no need to track notifications.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5703
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
#define MAX_SECS 100000000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
 * This code is common to linux and solaris and will be moved to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
 * common place in dolphin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
 * The passed in time value is either a relative time in nanoseconds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
 * or an absolute time in milliseconds. Either way it has to be unpacked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
 * into suitable seconds and nanoseconds components and stored in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
 * given timespec structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
 * Given time is a 64-bit value and the time_t used in the timespec is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5716
 * overflow if times way in the future are given. Further on Solaris versions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5717
 * prior to 10 there is a restriction (see cond_timedwait) that the specified
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5718
 * number of seconds, in abstime, is less than current_time  + 100,000,000.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
 * As it will be 28 years before "now + 100000000" will overflow we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
 * ignore overflow and just impose a hard-limit on seconds using the value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5721
 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5722
 * years from "now".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
  assert (time > 0, "convertTime");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5728
  struct timeval now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
  int status = gettimeofday(&now, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
  assert(status == 0, "gettimeofday");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
  time_t max_secs = now.tv_sec + MAX_SECS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
  if (isAbsolute) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5735
    jlong secs = time / 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5736
    if (secs > max_secs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5737
      absTime->tv_sec = max_secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5738
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5739
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5740
      absTime->tv_sec = secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5741
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5742
    absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5743
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5744
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5745
    jlong secs = time / NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5746
    if (secs >= MAX_SECS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5747
      absTime->tv_sec = max_secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5748
      absTime->tv_nsec = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5749
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5750
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5751
      absTime->tv_sec = now.tv_sec + secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5752
      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5753
      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5754
        absTime->tv_nsec -= NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5755
        ++absTime->tv_sec; // note: this must be <= max_secs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5756
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5757
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
  assert(absTime->tv_sec >= 0, "tv_sec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
void Parker::park(bool isAbsolute, jlong time) {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5766
  // Ideally we'd do something useful while spinning, such
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5767
  // as calling unpackTime().
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5768
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5769
  // Optional fast-path check:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5770
  // Return immediately if a permit is available.
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5771
  // We depend on Atomic::xchg() having full barrier semantics
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5772
  // since we are doing a lock-free update to _counter.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5773
  if (Atomic::xchg(0, &_counter) > 0) return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5775
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5776
  assert(thread->is_Java_thread(), "Must be JavaThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5777
  JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5779
  // Optional optimization -- avoid state transitions if there's an interrupt pending.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
  // Check interrupt before trying to wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
  if (Thread::is_interrupted(thread, false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5783
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
  // Next, demultiplex/decode time arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
  timespec absTime;
6962
d49132ce025b 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 6420
diff changeset
  5787
  if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
  if (time > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
    unpackTime(&absTime, isAbsolute, time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
  // Enter safepoint region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
  // Beware of deadlocks such as 6317397.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5797
  // The per-thread Parker:: mutex is a classic leaf-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
  // In particular a thread must never block on the Threads_lock while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
  // holding the Parker:: mutex.  If safepoints are pending both the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5800
  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5801
  ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5803
  // Don't wait if cannot get lock since interference arises from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5804
  // unblocking.  Also. check interrupt before trying wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5805
  if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5806
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5807
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5809
  int status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5810
  if (_counter > 0)  { // no wait needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5811
    _counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5812
    status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5813
    assert (status == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5814
    // Paranoia to ensure our locked and lock-free paths interact
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5815
    // correctly with each other and Java-level accesses.
4487
de1359156181 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 4013
diff changeset
  5816
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5817
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5818
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5820
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5821
  // Don't catch signals while blocked; let the running threads have the signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5822
  // (This allows a debugger to break into the running thread.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5823
  sigset_t oldsigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5824
  sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5825
  pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5826
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5827
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5828
  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5829
  jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5830
  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5832
  if (time == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5833
    status = pthread_cond_wait (_cond, _mutex) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5835
    status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5836
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5837
      pthread_cond_destroy (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5838
      pthread_cond_init    (_cond, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5839
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5840
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5841
  assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5842
                status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
                status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5845
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5847
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
  _counter = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
  status = pthread_mutex_unlock(_mutex) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
  assert_status(status == 0, status, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5852
  // Paranoia to ensure our locked and lock-free paths interact
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5853
  // correctly with each other and Java-level accesses.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5854
  OrderAccess::fence();
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5855
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
  // If externally suspended while waiting, re-suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
  if (jt->handle_special_suspend_equivalent_condition()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
    jt->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5862
void Parker::unpark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5863
  int s, status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
  status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
  assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5866
  s = _counter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5867
  _counter = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5868
  if (s < 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5869
     if (WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5870
        status = pthread_cond_signal (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5871
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5872
        status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5874
     } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5875
        status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
        status = pthread_cond_signal (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5878
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
    pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5882
    assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5883
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5884
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5885
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5886
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5887
extern char** environ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5888
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
#ifndef __NR_fork
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5890
#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5891
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5893
#ifndef __NR_execve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5895
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
// Run the specified command in a separate process. Return its exit value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
// or -1 on failure (e.g. can't fork a new process).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
// Unlike system(), this function can be called from signal handler. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5900
// doesn't block SIGINT et al.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
int os::fork_and_exec(char* cmd) {
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
  5902
  const char * argv[4] = {"sh", "-c", cmd, NULL};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5903
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5905
  // pthread_atfork handlers and reset pthread library. All we need is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5906
  // separate process to execve. Make a direct syscall to fork process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5907
  // On IA64 there's no fork syscall, we have to use fork() and hope for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5908
  // the best...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5909
  pid_t pid = NOT_IA64(syscall(__NR_fork);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5910
              IA64_ONLY(fork();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5912
  if (pid < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5913
    // fork failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5916
  } else if (pid == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5917
    // child process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
    // execve() in LinuxThreads will call pthread_kill_other_threads_np()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
    // first to kill every thread on the thread list. Because this list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
    // not reset by fork() (see notes above), execve() will instead kill
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
    // every thread in the parent process. We know this is the only thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
    // in the new process, so make a system call directly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
    // IA64 should use normal execve() from glibc to match the glibc fork()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5925
    // above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5926
    NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
  5927
    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5929
    // execve failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5930
    _exit(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5932
  } else  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5933
    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
    // care about the actual exit code, for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5936
    int status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5937
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
    // Wait for the child process to exit.  This returns immediately if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5939
    // the child has already exited. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
    while (waitpid(pid, &status, 0) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5941
        switch (errno) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5942
        case ECHILD: return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5943
        case EINTR: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5944
        default: return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5945
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5946
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5948
    if (WIFEXITED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5949
       // The child exited normally; get its exit code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
       return WEXITSTATUS(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5951
    } else if (WIFSIGNALED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5952
       // The child exited because of a signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5953
       // The best value to return is 0x80 + signal number,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5954
       // because that is what all Unix shells do, and because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
       // it allows callers to distinguish between process exit and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
       // process death by signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
       return 0x80 + WTERMSIG(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
       // Unknown exit code; pass it through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
       return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5963
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5964
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5965
// is_headless_jre()
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5966
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5967
// Test for the existence of xawt/libmawt.so or libawt_xawt.so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5968
// in order to report if we are running in a headless jre
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5969
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5970
// Since JDK8 xawt/libmawt.so was moved into the same directory
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5971
// as libawt.so, and renamed libawt_xawt.so
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5972
//
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5973
bool os::is_headless_jre() {
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5974
    struct stat statbuf;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5975
    char buf[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5976
    char libmawtpath[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5977
    const char *xawtstr  = "/xawt/libmawt.so";
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5978
    const char *new_xawtstr = "/libawt_xawt.so";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5979
    char *p;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5980
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5981
    // Get path to libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5982
    os::jvm_path(buf, sizeof(buf));
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5983
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5984
    // Get rid of libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5985
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5986
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5987
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5988
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5989
    // Get rid of client or server
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5990
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5991
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5992
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5993
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5994
    // check xawt/libmawt.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5995
    strcpy(libmawtpath, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5996
    strcat(libmawtpath, xawtstr);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5997
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5998
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5999
    // check libawt_xawt.so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6000
    strcpy(libmawtpath, buf);
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  6001
    strcat(libmawtpath, new_xawtstr);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6002
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6003
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6004
    return true;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6005
}
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6006
13198
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6007
// Get the default path to the core file
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6008
// Returns the length of the string
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6009
int os::get_core_path(char* buffer, size_t bufferSize) {
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6010
  const char* p = get_current_directory(buffer, bufferSize);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6011
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6012
  if (p == NULL) {
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6013
    assert(p != NULL, "failed to get current directory");
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6014
    return 0;
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6015
  }
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6016
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6017
  return strlen(buffer);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6018
}
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6019
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6020
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6021
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6022
// A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6023
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6024
MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6026
// ctor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6027
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6028
MemNotifyThread::MemNotifyThread(int fd): Thread() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6029
  assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6030
  _fd = fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6031
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6032
  if (os::create_thread(this, os::os_thread)) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6033
    _memnotify_thread = this;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6034
    os::set_priority(this, NearMaxPriority);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6035
    os::start_thread(this);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6036
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6037
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6038
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6039
// Where all the work gets done
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6040
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6041
void MemNotifyThread::run() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6042
  assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6043
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6044
  // Set up the select arguments
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6045
  fd_set rfds;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6046
  if (_fd != -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6047
    FD_ZERO(&rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6048
    FD_SET(_fd, &rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6049
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6050
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6051
  // Now wait for the mem_notify device to wake up
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6052
  while (1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6053
    // Wait for the mem_notify device to signal us..
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6054
    int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6055
    if (rc == -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6056
      perror("select!\n");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6057
      break;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6058
    } else if (rc) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6059
      //ssize_t free_before = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6060
      //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6061
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6062
      // The kernel is telling us there is not much memory left...
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6063
      // try to do something about that
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6064
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6065
      // If we are not already in a GC, try one.
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6066
      if (!Universe::heap()->is_gc_active()) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6067
        Universe::heap()->collect(GCCause::_allocation_failure);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6068
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6069
        //ssize_t free_after = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6070
        //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6071
        //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6072
      }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6073
      // We might want to do something like the following if we find the GC's are not helping...
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6074
      // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6075
    }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6076
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6077
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6078
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6079
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6080
// See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6081
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6082
void MemNotifyThread::start() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6083
  int    fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6084
  fd = open ("/dev/mem_notify", O_RDONLY, 0);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6085
  if (fd < 0) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6086
      return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6087
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6088
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6089
  if (memnotify_thread() == NULL) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6090
    new MemNotifyThread(fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6091
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6092
}
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  6093
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6094
#endif // JAVASE_EMBEDDED
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6095
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6096
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6097
/////////////// Unit tests ///////////////
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6098
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6099
#ifndef PRODUCT
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6100
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6101
#define test_log(...) \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6102
  do {\
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6103
    if (VerboseInternalVMTests) { \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6104
      tty->print_cr(__VA_ARGS__); \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6105
      tty->flush(); \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6106
    }\
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6107
  } while (false)
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6108
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6109
class TestReserveMemorySpecial : AllStatic {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6110
 public:
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6111
  static void small_page_write(void* addr, size_t size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6112
    size_t page_size = os::vm_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6113
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6114
    char* end = (char*)addr + size;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6115
    for (char* p = (char*)addr; p < end; p += page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6116
      *p = 1;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6117
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6118
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6119
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6120
  static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6121
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6122
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6123
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6124
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6125
    test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6126
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6127
    char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6128
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6129
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6130
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6131
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6132
      os::Linux::release_memory_special_huge_tlbfs(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6133
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6134
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6135
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6136
  static void test_reserve_memory_special_huge_tlbfs_only() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6137
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6138
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6139
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6140
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6141
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6142
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6143
    for (size_t size = lp; size <= lp * 10; size += lp) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6144
      test_reserve_memory_special_huge_tlbfs_only(size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6145
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6146
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6147
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6148
  static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6149
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6150
        return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6151
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6152
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6153
    test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")",
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6154
        size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6155
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6156
    assert(size >= os::large_page_size(), "Incorrect input to test");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6157
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6158
    char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6159
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6160
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6161
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6162
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6163
      os::Linux::release_memory_special_huge_tlbfs(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6164
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6165
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6166
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6167
  static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6168
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6169
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6170
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6171
    for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6172
      test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6173
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6174
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6175
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6176
  static void test_reserve_memory_special_huge_tlbfs_mixed() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6177
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6178
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6179
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6180
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6181
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6182
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6183
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6184
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6185
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6186
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6187
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6188
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6189
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6190
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6191
  static void test_reserve_memory_special_huge_tlbfs() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6192
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6193
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6194
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6195
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6196
    test_reserve_memory_special_huge_tlbfs_only();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6197
    test_reserve_memory_special_huge_tlbfs_mixed();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6198
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6199
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6200
  static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6201
    if (!UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6202
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6203
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6204
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6205
    test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6206
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6207
    char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6208
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6209
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6210
      assert(is_ptr_aligned(addr, alignment), "Check");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6211
      assert(is_ptr_aligned(addr, os::large_page_size()), "Check");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6212
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6213
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6214
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6215
      os::Linux::release_memory_special_shm(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6216
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6217
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6218
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6219
  static void test_reserve_memory_special_shm() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6220
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6221
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6222
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6223
    for (size_t size = ag; size < lp * 3; size += ag) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6224
      for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6225
        test_reserve_memory_special_shm(size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6226
      }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6227
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6228
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6229
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6230
  static void test() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6231
    test_reserve_memory_special_huge_tlbfs();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6232
    test_reserve_memory_special_shm();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6233
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6234
};
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6235
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6236
void TestReserveMemorySpecial_test() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6237
  TestReserveMemorySpecial::test();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6238
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6239
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6240
#endif