hotspot/src/os/linux/vm/os_linux.cpp
author stefank
Sat, 05 Oct 2013 10:14:58 +0200
changeset 20400 1c658ebcb3c1
parent 20005 6fb8070af25d
child 20408 ca559663042f
permissions -rw-r--r--
8024838: Significant slowdown due to transparent huge pages Summary: Don't turn on transparent huge pages (-XX:+UseTransparentHugePages) unless explicitly specified on the command line. This has the effect that large pages are never turned on Linux unless the user has explicitly enabled any of the large pages flags: -XX:+UseLargePages, -XX:+UseTransparentHugePages, -XX:+UseHugeTLBFS, and -XX:+UseSHM. Reviewed-by: jwilhelm, tschatzl, brutisso
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;
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
   134
pthread_condattr_t os::Linux::_condattr[1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
static jlong initial_time_count=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
static int clock_tics_per_sec = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
// For diagnostics to print a message once. see run_periodic_checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
static sigset_t check_signal_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
static bool check_signals = true;;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
static pid_t _initial_pid = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
/* Signal number used to suspend/resume a thread */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
/* do not use any signal number less than SIGSEGV, see 4355769 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
static int SR_signum = SIGUSR2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
sigset_t SR_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   152
/* Used to protect dlsym() calls */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   153
static pthread_mutex_t dl_mutex;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   154
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   155
// Declarations
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   156
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   157
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   158
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   159
class MemNotifyThread: public Thread {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   160
  friend class VMStructs;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   161
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   162
  virtual void run();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   163
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   164
 private:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   165
  static MemNotifyThread* _memnotify_thread;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   166
  int _fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   167
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   168
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   169
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   170
  // Constructor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   171
  MemNotifyThread(int fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   172
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   173
  // Tester
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   174
  bool is_memnotify_thread() const { return true; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   175
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   176
  // Printing
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   177
  char* name() const { return (char*)"Linux MemNotify Thread"; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   178
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   179
  // Returns the single instance of the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   180
  static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   181
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   182
  // Create and start the single instance of MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   183
  static void start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   184
};
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   185
#endif // JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   186
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
// utility functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
static int SR_initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
julong os::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  return Linux::available_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
julong os::Linux::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  return (julong)si.freeram * si.mem_unit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
julong os::physical_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  return Linux::physical_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
// environment support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
bool os::getenv(const char* name, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  const char* val = ::getenv(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
  if (val != NULL && strlen(val) < (size_t)len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    strcpy(buf, val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  if (len > 0) buf[0] = 0;  // return a null string
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
// Return true if user is running as root.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
bool os::have_special_privileges() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  static bool privileges = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  if (!init) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    privileges = (getuid() != geteuid()) || (getgid() != getegid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
  return privileges;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
#ifndef SYS_gettid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
// i386: 224, ia64: 1105, amd64: 186, sparc 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
#ifdef __ia64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
#define SYS_gettid 1105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
#elif __i386__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
#define SYS_gettid 224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
#elif __amd64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
#define SYS_gettid 186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
#elif __sparc__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
#define SYS_gettid 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
#error define gettid for the arch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
// Cpu architecture string
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   250
#if   defined(ZERO)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   251
static char cpu_arch[] = ZERO_LIBARCH;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   252
#elif defined(IA64)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
static char cpu_arch[] = "ia64";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
#elif defined(IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
static char cpu_arch[] = "i386";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
#elif defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
static char cpu_arch[] = "amd64";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   258
#elif defined(ARM)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   259
static char cpu_arch[] = "arm";
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   260
#elif defined(PPC)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   261
static char cpu_arch[] = "ppc";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
#elif defined(SPARC)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
#  ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
static char cpu_arch[] = "sparcv9";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
#  else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
static char cpu_arch[] = "sparc";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
#  endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
#error Add appropriate cpu_arch setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
// pid_t gettid()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
// Returns the kernel thread id of the currently running thread. Kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
// thread id is used to access /proc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
// (Note that getpid() on LinuxThreads returns kernel thread id too; but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
// on NPTL, it returns the same pid for all threads, as required by POSIX.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
pid_t os::Linux::gettid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  int rslt = syscall(SYS_gettid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
  if (rslt == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
     // old kernel, no NPTL support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
     return getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
     return (pid_t)rslt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
// Most versions of linux have a bug where the number of processors are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
// determined by looking at the /proc file system.  In a chroot environment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
// the system call returns 1.  This causes the VM to act as if it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
// a single processor and elide locking (see is_MP() call).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
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
   296
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
   297
                     "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
   298
                     "environment on Linux when /proc filesystem is not mounted.";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
void os::Linux::initialize_system_info() {
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   301
  set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   302
  if (processor_count() == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    FILE *fp = fopen(fname, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
    if (fp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
      unsafe_chroot_detected = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
  _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
   314
  assert(processor_count() > 0, "linux error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
void os::init_system_properties_values() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
//  char arch[12];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
//  sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  // The next steps are taken in the product version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
  //
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   323
  // Obtain the JAVA_HOME value from the location of libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
  // This library should be located at:
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   325
  // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
  // 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
   328
  // assume libjvm.so is installed in a JDK and we use this path.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  // Otherwise exit with message: "Could not create the Java virtual machine."
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  // The following extra steps are taken in the debugging version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // If "/jre/lib/" does NOT appear at the right place in the path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  // instead of exit check for $JAVA_HOME environment variable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
  // 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
   338
  // 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
   339
  // it looks like libjvm.so is installed there
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   340
  // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  // Otherwise exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  // Important note: if the location of libjvm.so changes this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
  // code needs to be changed accordingly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
  // The next few definitions allow the code to be verbatim:
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   348
#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
#define getenv(n) ::getenv(n)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
 * See ld(1):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
 *      The linker uses the following search paths to locate required
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
 *      shared libraries:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
 *        1: ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
 *        ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
 *        7: The default directories, normally /lib and /usr/lib.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
 */
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   359
#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
   360
#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
   361
#else
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
#define DEFAULT_LIBPATH "/lib:/usr/lib"
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   363
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
#define EXTENSIONS_DIR  "/lib/ext"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
#define ENDORSED_DIR    "/lib/endorsed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
#define REG_DIR         "/usr/java/packages"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    /* sysclasspath, java_home, dll_dir */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        char *home_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
        char *dll_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
        char *pslash;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
        char buf[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
        os::jvm_path(buf, sizeof(buf));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
        // Found the full path to libjvm.so.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        // Now cut the path to <java_home>/jre if we can.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        *(strrchr(buf, '/')) = '\0';  /* get rid of /libjvm.so */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
        pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
        if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
            *pslash = '\0';           /* get rid of /{client|server|hotspot} */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
        dll_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
        if (dll_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
        strcpy(dll_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
        Arguments::set_dll_dir(dll_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
        if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
            pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
            if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
                *pslash = '\0';       /* get rid of /<arch> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
                pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
                if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
                    *pslash = '\0';   /* get rid of /lib */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
        home_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
        if (home_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        strcpy(home_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
        Arguments::set_java_home(home_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
        if (!set_boot_path('/', ':'))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
     * Where to look for native libraries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
     * Note: Due to a legacy implementation, most of the library path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
     * is set in the launcher.  This was to accomodate linking restrictions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
     * on legacy Linux implementations (which are no longer supported).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
     * However, to prevent the proliferation of improperly built native
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
     * libraries, the new path component /usr/java/packages is added here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
        char *ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
         * Construct the invariant part of ld_library_path. Note that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
         * space for the colon and the trailing null are provided by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
         * nulls included by the sizeof operator (so actually we allocate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
         * a byte more than necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
        ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
            strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
        sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
         * Get the user setting of LD_LIBRARY_PATH, and prepended it.  It
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
         * should always exist (until the legacy problem cited above is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
         * addressed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
        char *v = getenv("LD_LIBRARY_PATH");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
        if (v != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
            char *t = ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
            /* That's +1 for the colon and +1 for the trailing '\0' */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
            ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
            sprintf(ld_library_path, "%s:%s", v, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
        Arguments::set_library_path(ld_library_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
     * Extensions directories.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
     * Note that the space for the colon and the trailing null are provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
     * by the nulls included by the sizeof operator (so actually one byte more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
     * than necessary is allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
        char *buf = malloc(strlen(Arguments::get_java_home()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
            sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
        sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
            Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
        Arguments::set_ext_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    /* Endorsed standards default directory. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
        char * buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
        buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
        sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
        Arguments::set_endorsed_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
#undef malloc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
#undef getenv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
#undef EXTENSIONS_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
#undef ENDORSED_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  // Done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
// breakpoint support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
void os::breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  BREAKPOINT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
extern "C" void breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  // use debugger to set breakpoint here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
// signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
debug_only(static bool signal_sets_initialized = false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
bool os::Linux::is_sig_ignored(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      struct sigaction oact;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      sigaction(sig, (struct sigaction*)NULL, &oact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
      void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*,  oact.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
                                     : CAST_FROM_FN_PTR(void*,  oact.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
      if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
      else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
           return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
void os::Linux::signal_sets_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  // Should also have an assertion stating we are still single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  assert(!signal_sets_initialized, "Already initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // Fill in signals that are necessarily unblocked for all threads in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  // the VM. Currently, we unblock the following signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  //                         by -Xrs (=ReduceSignalUsage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // other threads. The "ReduceSignalUsage" boolean tells us not to alter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // the dispositions or masks wrt these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // Programs embedding the VM that want to use the above signals for their
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  // own purposes must, at this time, use the "-Xrs" option to prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // (See bug 4345157, and other related bugs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  // In reality, though, unblocking these signals is really a nop, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  // these signals are not blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  sigemptyset(&unblocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  sigemptyset(&allowdebug_blocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  sigaddset(&unblocked_sigs, SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  sigaddset(&unblocked_sigs, SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  sigaddset(&unblocked_sigs, SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  sigaddset(&unblocked_sigs, SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
  sigaddset(&unblocked_sigs, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
   if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
   if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
   if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  // Fill in signals that are blocked by all but the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  sigemptyset(&vm_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  if (!ReduceSignalUsage)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
    sigaddset(&vm_sigs, BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  debug_only(signal_sets_initialized = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
// These are signals that are unblocked while a thread is running Java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
// (For some reason, they get blocked by default.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
sigset_t* os::Linux::unblocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  return &unblocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
// These are the signals that are blocked while a (non-VM) thread is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
// running Java. Only the VM thread handles these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
sigset_t* os::Linux::vm_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  return &vm_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
// These are signals that are blocked during cond_wait to allow debugger in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
sigset_t* os::Linux::allowdebug_blocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
  return &allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
void os::Linux::hotspot_sigmask(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  //Save caller's signal mask before setting VM signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  sigset_t caller_sigmask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  osthread->set_caller_sigmask(caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    if (thread->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      // Only the VM thread handles BREAK_SIGNAL ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
      pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      // ... all other threads block BREAK_SIGNAL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
      pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
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
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
// detecting pthread library
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
void os::Linux::libpthread_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // generic name for earlier versions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  // Define macros here so we can build HotSpot on old systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
# ifndef _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
# define _CS_GNU_LIBC_VERSION 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
# ifndef _CS_GNU_LIBPTHREAD_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
# define _CS_GNU_LIBPTHREAD_VERSION 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   616
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
     confstr(_CS_GNU_LIBC_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
     os::Linux::set_glibc_version(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
     // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
     static char _gnu_libc_version[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
     jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
              "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
     os::Linux::set_glibc_version(_gnu_libc_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   629
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
     confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
     // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
     // 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
   633
     // 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
   634
     // 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
   635
     // 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
   636
     // will return -1 and errno is not changed. Check if it is really NPTL.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
     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
   638
         strstr(str, "NPTL") &&
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   639
         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
   640
       free(str);
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   641
       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
   642
     } else {
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   643
       os::Linux::set_libpthread_version(str);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
  } else {
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   646
    // 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
   647
    os::Linux::set_libpthread_version("linuxthreads");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
  if (strstr(libpthread_version(), "NPTL")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
     os::Linux::set_is_NPTL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
     os::Linux::set_is_LinuxThreads();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  // LinuxThreads have two flavors: floating-stack mode, which allows variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  // stack size; and fixed-stack mode. NPTL is always floating-stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
  if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
     os::Linux::set_is_floating_stack();
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
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
// thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// Force Linux kernel to expand current thread stack. If "bottom" is close
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
// to the stack guard, caller should block all signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
// MAP_GROWSDOWN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
//   A special mmap() flag that is used to implement thread stacks. It tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
//   kernel that the memory region should extend downwards when needed. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
//   allows early versions of LinuxThreads to only mmap the first few pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
//   when creating a new thread. Linux kernel will automatically expand thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
//   stack as needed (on page faults).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
//   However, because the memory region of a MAP_GROWSDOWN stack can grow on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
//   demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
//   region, it's hard to tell if the fault is due to a legitimate stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
//   access or because of reading/writing non-exist memory (e.g. buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
//   overrun). As a rule, if the fault happens below current stack pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
//   Linux kernel does not expand stack, instead a SIGSEGV is sent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
//   application (see Linux kernel fault.c).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
//   This Linux feature can cause SIGSEGV when VM bangs thread stack for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
//   stack overflow detection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
//   Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
//   not use this flag. However, the stack of initial thread is not created
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
//   by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
//   unlikely) that user code can create a thread with MAP_GROWSDOWN stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
//   and then attach the thread to JVM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
// To get around the problem and allow stack banging on Linux, we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
// manually expand thread stack after receiving the SIGSEGV.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
// There are two ways to expand thread stack to address "bottom", we used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
// both of them in JVM before 1.5:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
//   1. adjust stack pointer first so that it is below "bottom", and then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
//      touch "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
//   2. mmap() the page in question
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
// Now alternate signal stack is gone, it's harder to use 2. For instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
// if current sp is already near the lower end of page 101, and we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
// call mmap() to map page 100, it is possible that part of the mmap() frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
// will be placed in page 100. When page 100 is mapped, it is zero-filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
// That will destroy the mmap() frame and cause VM to crash.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
// The following code works by adjusting sp first, then accessing the "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
// page to force a page fault. Linux kernel will then automatically expand the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
// stack mapping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
// _expand_stack_to() assumes its frame size is less than page size, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
// should always be true if the function is not inlined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
#if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
#define NOINLINE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
#define NOINLINE __attribute__ ((noinline))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
static void _expand_stack_to(address bottom) NOINLINE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
static void _expand_stack_to(address bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  address sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  volatile char *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  // Adjust bottom to point to the largest address within the same page, it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  // gives us a one-page buffer if alloca() allocates slightly more memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  bottom += os::Linux::page_size() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // sp might be slightly above current stack pointer; if that's the case, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  // will alloca() a little more space than necessary, which is OK. Don't use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  // os::current_stack_pointer(), as its result can be slightly below current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  // stack pointer, causing us to not alloca enough to reach "bottom".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  sp = (address)&sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  if (sp > bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    size = sp - bottom;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    p = (volatile char *)alloca(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
    p[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  assert(t!=NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  assert(t->osthread()->expanding_stack(), "expand should be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  assert(t->stack_base() != NULL, "stack_base was not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
  if (addr <  t->stack_base() && addr >= t->stack_yellow_zone_base()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    sigset_t mask_all, old_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    sigfillset(&mask_all);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    _expand_stack_to(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
// create new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
static address highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
// check if it's safe to start a new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
static bool _thread_safety_check(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
  if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    //   Heap is mmap'ed at lower end of memory space. Thread stacks are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    //   allocated (MAP_FIXED) from high address space. Every thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    //   occupies a fixed size slot (usually 2Mbytes, but user can change
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    //   it to other values if they rebuild LinuxThreads).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    // Problem with MAP_FIXED is that mmap() can still succeed even part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    // the memory region has already been mmap'ed. That means if we have too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    // many threads and/or very large heap, eventually thread stack will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    // collide with heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    // Here we try to prevent heap/stack collision by comparing current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    // stack bottom with the highest address that has been mmap'ed by JVM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    // plus a safety margin for memory maps created by native code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    // This feature can be disabled by setting ThreadSafetyMargin to 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
    if (ThreadSafetyMargin > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
      address stack_bottom = os::current_stack_base() - os::current_stack_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
      // not safe if our stack extends below the safety margin
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
      return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    // Floating stack LinuxThreads or NPTL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    //   Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
    //   there's not enough space left, pthread_create() will fail. If we come
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    //   here, that means enough space has been reserved for stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
// Thread start routine for all newly created threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
static void *java_start(Thread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  // Try to randomize the cache line index of hot stack frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  // This helps when threads of the same stack traces evict each other's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  // cache lines. The threads can be either from the same JVM instance, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  // from different JVM instances. The benefit is especially true for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  // processors with hyperthreading technology.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  static int counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  int pid = os::current_process_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
  alloca(((pid ^ counter++) & 7) * 128);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  ThreadLocalStorage::set_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
  Monitor* sync = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  // non floating stack LinuxThreads needs extra check, see above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
  if (!_thread_safety_check(thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    osthread->set_state(ZOMBIE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  // thread_id is kernel thread id (similar to Solaris LWP id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  // handshaking with parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    osthread->set_state(INITIALIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
    // wait until os::start_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
    while (osthread->get_state() == INITIALIZED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
      sync->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  // call one more level start routine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
  thread->run();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
  assert(thread->osthread() == NULL, "caller responsible");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  // set the correct thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
  osthread->set_thread_type(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  // Initial state is ALLOCATED but not INITIALIZED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  osthread->set_state(ALLOCATED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  // init thread attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  pthread_attr_t attr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  pthread_attr_init(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  // stack size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
  if (os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
    // calculate stack size if it's not specified by caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
    if (stack_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
      stack_size = os::Linux::default_stack_size(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      switch (thr_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
      case os::java_thread:
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   895
        // Java threads use ThreadStackSize which default value can be
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   896
        // changed with the flag -Xss
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   897
        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
   898
        stack_size = JavaThread::stack_size_at_create();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
      case os::compiler_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
        if (CompilerThreadStackSize > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
          stack_size = (size_t)(CompilerThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
        } // else fall through:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
          // use VMThreadStackSize if CompilerThreadStackSize is not defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
      case os::vm_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      case os::pgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
      case os::cgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
      case os::watcher_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
        if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
    pthread_attr_setstacksize(&attr, stack_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    // let pthread_create() pick the default value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
  // glibc guard page
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
  pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  ThreadState state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
    // Serialize thread creation if we are running with fixed stack LinuxThreads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
      os::Linux::createThread_lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    pthread_t tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    pthread_attr_destroy(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    if (ret != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
      if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
        perror("pthread_create()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
      // Need to clean up stuff we've allocated so far
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      if (lock) os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
    // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
    osthread->set_pthread_id(tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    // Wait until child thread is either initialized or aborted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
      Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
      MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
      while ((state = osthread->get_state()) == ALLOCATED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
        sync_with_child->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
      os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  // Aborted due to thread limit being reached
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
  if (state == ZOMBIE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  // The thread is returned suspended (in state INITIALIZED),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  // and is started higher up in the call chain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  assert(state == INITIALIZED, "race condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
// attach existing thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
// bootstrap the main thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
bool os::create_main_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  return create_attached_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
bool os::create_attached_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
    thread->verify_not_published();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
  osthread->set_pthread_id(::pthread_self());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  // Initial thread state is RUNNABLE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
  osthread->set_state(RUNNABLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  if (os::Linux::is_initial_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
    // If current thread is initial thread, its stack is mapped on demand,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    // the entire stack region to avoid SEGV in stack banging.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    // It is also useful to get around the heap-stack-gap problem on SuSE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
    // kernel (see 4821821 for details). We first expand stack to the top
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
    // of yellow zone, then enable stack yellow zone (order is significant,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
    // enabling yellow zone first will crash JVM on SuSE Linux), so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
    // is no gap between the last two virtual memory regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    address addr = jt->stack_yellow_zone_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    assert(addr != NULL, "initialization problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
    assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    osthread->set_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    os::Linux::manually_expand_stack(jt, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
    osthread->clear_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  // and save the caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
void os::pd_start_thread(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  OSThread * osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  assert(osthread->get_state() != INITIALIZED, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
  sync_with_child->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
// Free Linux resources related to the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
void os::free_thread(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
  assert(osthread != NULL, "osthread not set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
  if (Thread::current()->osthread() == osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    // Restore caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    sigset_t sigmask = osthread->caller_sigmask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
    pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
  delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
// thread local storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
int os::allocate_thread_local_storage() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  pthread_key_t key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  int rslt = pthread_key_create(&key, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  assert(rslt == 0, "cannot allocate thread local storage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
  return (int)key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
// Note: This is currently not used by VM, as we don't destroy TLS key
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
// on VM exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
void os::free_thread_local_storage(int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  int rslt = pthread_key_delete((pthread_key_t)index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
  assert(rslt == 0, "invalid index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
void os::thread_local_storage_at_put(int index, void* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  int rslt = pthread_setspecific((pthread_key_t)index, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
  assert(rslt == 0, "pthread_setspecific failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
extern "C" Thread* get_thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
  return ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
// initial thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
// Check if current thread is the initial thread, similar to Solaris thr_main.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
bool os::Linux::is_initial_thread(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  char dummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  // If called before init complete, thread stack bottom will be null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  // Can be called if fatal error occurs before initialization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  if (initial_thread_stack_bottom() == NULL) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  assert(initial_thread_stack_bottom() != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
         initial_thread_stack_size()   != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
         "os::init did not locate initial thread's stack region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  if ((address)&dummy >= initial_thread_stack_bottom() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
      (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
       return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
  else return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
// Find the virtual memory area that contains addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
static bool find_vma(address addr, address* vma_low, address* vma_high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  FILE *fp = fopen("/proc/self/maps", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
  if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
    address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
    while (!feof(fp)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
      if (fscanf(fp, "%p-%p", &low, &high) == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
        if (low <= addr && addr < high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
           if (vma_low)  *vma_low  = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
           if (vma_high) *vma_high = high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
           fclose (fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
      for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
        int ch = fgetc(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
        if (ch == EOF || ch == (int)'\n') break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
    fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
// Locate initial thread stack. This special handling of initial thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
// is needed because pthread_getattr_np() on most (all?) Linux distros returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
// bogus value for initial thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
void os::Linux::capture_initial_stack(size_t max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  // stack size is the easy part, get it from RLIMIT_STACK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  size_t stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  struct rlimit rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  getrlimit(RLIMIT_STACK, &rlim);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
  stack_size = rlim.rlim_cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  // 6308388: a bug in ld.so will relocate its own .data section to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  //   lower end of primordial stack; reduce ulimit -s value a little bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  //   so we won't install guard page on ld.so's data section.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
  stack_size -= 2 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
  // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  //   7.1, in both cases we will get 2G in return value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  //   SuSE 7.2, Debian) can not handle alternate signal stack correctly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
  //   for initial thread if its stack size exceeds 6M. Cap it at 2M,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  //   in case other parts in glibc still assumes 2M max stack size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  // FIXME: alt signal stack is gone, maybe we can relax this constraint?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
  // 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
  1158
  if (stack_size > 2 * K * K IA64_ONLY(*2))
73896d91270c 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 15234
diff changeset
  1159
      stack_size = 2 * K * K IA64_ONLY(*2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
  // Try to figure out where the stack base (top) is. This is harder.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  // When an application is started, glibc saves the initial stack pointer in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  // a global variable "__libc_stack_end", which is then used by system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  // libraries. __libc_stack_end should be pretty close to stack top. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  // variable is available since the very early days. However, because it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  // a private interface, it could disappear in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  // to __libc_stack_end, it is very close to stack top, but isn't the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  // stack top. Note that /proc may not exist if VM is running as a chroot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  // program, so reading /proc/<pid>/stat could fail. Also the contents of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  // /proc/<pid>/stat could change in the future (though unlikely).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  // We try __libc_stack_end first. If that doesn't work, look for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  // /proc/<pid>/stat. If neither of them works, we use current stack pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  // as a hint, which should work well in most cases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
  uintptr_t stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  // try __libc_stack_end first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
  if (p && *p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
    stack_start = *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    // see if we can get the start_stack field from /proc/self/stat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    int pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
    char state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    int ppid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    int pgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    int session;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    int nr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    int tpgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    unsigned long flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
    unsigned long minflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
    unsigned long cminflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    unsigned long majflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
    unsigned long cmajflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
    unsigned long utime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    unsigned long stime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    long cutime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    long cstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    long prio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
    long nice;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    long junk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
    long it_real;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    uintptr_t start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1208
    uintptr_t vsize;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1209
    intptr_t rss;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1210
    uintptr_t rsslim;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
    uintptr_t scodes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    uintptr_t ecode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    // Figure what the primordial thread stack base is. Code is inspired
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
    // by email from Hans Boehm. /proc/self/stat begins with current pid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    // followed by command name surrounded by parentheses, state, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
    int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
    fp = fopen("/proc/self/stat", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
    if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
      // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
      // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
      //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
      // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
      // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
      char * s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
      if (s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
        // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
        do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1240
#define _UFM UINTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1241
#define _DFM INTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1242
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1243
        /*                                     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
  1244
        /*              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
  1245
        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
  1246
             &state,          /* 3  %c  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
             &ppid,           /* 4  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
             &pgrp,           /* 5  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
             &session,        /* 6  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
             &nr,             /* 7  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
             &tpgrp,          /* 8  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
             &flags,          /* 9  %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
             &minflt,         /* 10 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
             &cminflt,        /* 11 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
             &majflt,         /* 12 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
             &cmajflt,        /* 13 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
             &utime,          /* 14 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
             &stime,          /* 15 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
             &cutime,         /* 16 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
             &cstime,         /* 17 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
             &prio,           /* 18 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
             &nice,           /* 19 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
             &junk,           /* 20 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
             &it_real,        /* 21 %ld  */
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1265
             &start,          /* 22 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1266
             &vsize,          /* 23 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1267
             &rss,            /* 24 INTX_FORMAT  */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1268
             &rsslim,         /* 25 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1269
             &scodes,         /* 26 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1270
             &ecode,          /* 27 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1271
             &stack_start);   /* 28 UINTX_FORMAT */
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1274
#undef _UFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1275
#undef _DFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1276
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
      if (i != 28 - 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
         assert(false, "Bad conversion from /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
         // product mode - assume we are the initial thread, good luck in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
         // embedded case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
         warning("Can't detect initial thread stack location - bad conversion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
         stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
      // For some reason we can't open /proc/self/stat (for example, running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
      // FreeBSD with a Linux emulator, or inside chroot), this should work for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
      // most cases, so don't abort:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      warning("Can't detect initial thread stack location - no /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
      stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // Now we have a pointer (stack_start) very close to the stack top, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  // next thing to do is to figure out the exact location of stack top. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
  // can find out the virtual memory area that contains stack_start by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  // and its upper limit is the real stack top. (again, this would fail if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
  // running inside chroot, because /proc may not exist.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  uintptr_t stack_top;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
  if (find_vma((address)stack_start, &low, &high)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    // success, "high" is the true stack top. (ignore "low", because initial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
    // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
    stack_top = (uintptr_t)high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
    // failed, likely because /proc/self/maps does not exist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
    warning("Can't detect initial thread stack location - find_vma failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    // best effort: stack_start is normally within a few pages below the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    // stack top, use it as stack top, and reduce stack size so we won't put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
    // guard page outside stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
    stack_top = stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
    stack_size -= 16 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  // stack_top could be partially down the page so align it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
  stack_top = align_size_up(stack_top, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
  if (max_size && stack_size > max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
     _initial_thread_stack_size = max_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
     _initial_thread_stack_size = stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
  _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
// time support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
// Time since start-up in seconds to a fine granularity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
// Used by VMSelfDestructTimer and the MemProfiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
double os::elapsedTime() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
  return (double)(os::elapsed_counter()) * 0.000001;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
jlong os::elapsed_counter() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
jlong os::elapsed_frequency() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
  return (1000 * 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1349
bool os::supports_vtime() { return true; }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1350
bool os::enable_vtime()   { return false; }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1351
bool os::vtime_enabled()  { return false; }
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1352
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1353
double os::elapsedVTime() {
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1354
  struct rusage usage;
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1355
  int retval = getrusage(RUSAGE_THREAD, &usage);
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1356
  if (retval == 0) {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1357
    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
  1358
  } else {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1359
    // better than nothing, but not much
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1360
    return elapsedTime();
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1361
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1362
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1363
234
4da9c1bbc810 6667833: Remove CacheTimeMillis
sbohne
parents: 1
diff changeset
  1364
jlong os::javaTimeMillis() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
  return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
#ifndef CLOCK_MONOTONIC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
#define CLOCK_MONOTONIC (1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
void os::Linux::clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  // we do dlopen's in this particular order due to bug in linux
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  // dynamical loader (see 6348968) leading to crash on exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  void* handle = dlopen("librt.so.1", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
  if (handle == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
    handle = dlopen("librt.so", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
  if (handle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
    int (*clock_getres_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
    int (*clock_gettime_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
    if (clock_getres_func && clock_gettime_func) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
      // See if monotonic clock is supported by the kernel. Note that some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
      // early implementations simply return kernel jiffies (updated every
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
      // 1/100 or 1/1000 second). It would be bad to use such a low res clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
      // for nano time (though the monotonic property is still nice to have).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
      // It's fixed in newer kernels, however clock_getres() still returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
      // 1/HZ. We check if clock_getres() works, but will ignore its reported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
      // resolution for now. Hopefully as people move to new kernels, this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
      // won't be a problem.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
      struct timespec res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
      struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
      if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
          clock_gettime_func(CLOCK_MONOTONIC, &tp)  == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
        // yes, monotonic clock is supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
        _clock_gettime = clock_gettime_func;
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  1403
        return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
        // close librt if there is no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
        dlclose(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
  }
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  1410
  warning("No monotonic clock was available - timed services may " \
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  1411
          "be adversely affected if the time-of-day clock changes");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
#ifndef SYS_clock_getres
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
#if defined(IA32) || defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
#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
  1418
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
#else
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1420
#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
  1421
#define sys_clock_getres(x,y)  -1
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1424
#else
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1425
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
void os::Linux::fast_thread_clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  if (!UseLinuxPosixThreadCPUClocks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
      (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  // Switch to using fast clocks for thread cpu time if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
  // the sys_clock_getres() returns 0 error code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  // Note, that some kernels may support the current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
  // returned by the pthread_getcpuclockid().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  // If the fast Posix clocks are supported then the sys_clock_getres()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
  // must return at least tp.tv_sec == 0 which means a resolution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
  // better than 1 sec. This is extra check for reliability.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  if(pthread_getcpuclockid_func &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
     pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
     sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
    _supports_fast_thread_cpu_time = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
    _pthread_getcpuclockid = pthread_getcpuclockid_func;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
jlong os::javaTimeNanos() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
    struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
    int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    assert(status == 0, "gettime error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
    jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
    timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
    int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
    jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
    return 1000 * usecs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
    // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
    info_ptr->may_skip_backward = false;      // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
    info_ptr->may_skip_forward = false;       // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
    // gettimeofday - based on time in seconds since the Epoch thus does not wrap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
    // gettimeofday is a real time clock so it skips
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
    info_ptr->may_skip_backward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
    info_ptr->may_skip_forward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
  info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
// Return the real, user, and system times in seconds from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
// arbitrary fixed point in the past.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
bool os::getTimesSecs(double* process_real_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
                      double* process_user_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
                      double* process_system_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
  struct tms ticks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
  clock_t real_ticks = times(&ticks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
  if (real_ticks == (clock_t) (-1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
    double ticks_per_second = (double) clock_tics_per_sec;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
    *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
    *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
    *process_real_time = ((double) real_ticks) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
char * os::local_time_string(char *buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
  struct tm t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
  time_t long_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
  time(&long_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
  localtime_r(&long_time, &t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
               t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
               t.tm_hour, t.tm_min, t.tm_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
2012
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1522
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
  1523
  return localtime_r(clock, res);
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1524
}
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1525
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
// runtime exit support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
// Note: os::shutdown() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
// called from signal handler. Before adding something to os::shutdown(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
void os::shutdown() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
  // allow PerfMemory to attempt cleanup of any persistent resources
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
  perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
  // needs to remove object in file system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
  AttachListener::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
  // flush buffered output, finish log files
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
  ostream_abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  // Check for abort hook
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
  abort_hook_t abort_hook = Arguments::abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
  if (abort_hook != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
    abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
// Note: os::abort() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
// called from signal handler. Before adding something to os::abort(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
void os::abort(bool dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
  os::shutdown();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
  if (dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    fdStream out(defaultStream::output_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    out.print_raw("Current thread is ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
    char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
    out.print_raw_cr(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
    out.print_raw_cr("Dumping core ...");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
    ::abort(); // dump core
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
  ::exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
// Die immediately, no exit hook, no abort hook, no cleanup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
void os::die() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
  // _exit() on LinuxThreads only kills current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
  ::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
// unused on linux for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
void os::set_error_file(const char *logfile) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1580
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1581
// 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
  1582
// from src/solaris/hpi/src/system_md.c
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
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
  1585
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1586
  if (errno == 0)  return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1587
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1588
  const char *s = ::strerror(errno);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1589
  size_t n = ::strlen(s);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1590
  if (n >= len) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1591
    n = len - 1;
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
  ::strncpy(buf, s, n);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1594
  buf[n] = '\0';
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1595
  return n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1596
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1597
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
intx os::current_thread_id() { return (intx)pthread_self(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
int os::current_process_id() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  // Under the old linux thread library, linux gives each thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  // its own process id. Because of this each thread will return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
  // a different pid if this method were to return the result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
  // of getpid(2). Linux provides no api that returns the pid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
  // of the launcher thread for the vm. This implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
  // returns a unique pid, the pid of the launcher thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  // that starts the vm 'process'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  // Under the NPTL, getpid() returns the same pid as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  // launcher thread rather than a unique pid per thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  // Use gettid() if you want the old pre NPTL behaviour.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  // if you are looking for the result of a call to getpid() that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
  // returns a unique pid for the calling thread, then look at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
  // OSThread::thread_id() method in osThread_linux.hpp file
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
  return (int)(_initial_pid ? _initial_pid : getpid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
// DLL functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
const char* os::dll_file_extension() { return ".so"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
7901
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1624
// 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
  1625
// 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
  1626
const char* os::get_temp_directory() { return "/tmp"; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1628
static bool file_exists(const char* filename) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1629
  struct stat statbuf;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1630
  if (filename == NULL || strlen(filename) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1631
    return false;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1632
  }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1633
  return os::stat(filename, &statbuf) == 0;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1634
}
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1635
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1636
bool os::dll_build_name(char* buffer, size_t buflen,
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1637
                        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
  1638
  bool retval = false;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1639
  // Copied from libhpi
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1640
  const size_t pnamelen = pname ? strlen(pname) : 0;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1641
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1642
  // Return error on buffer overflow.
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1643
  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
  1644
    return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1645
  }
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1646
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1647
  if (pnamelen == 0) {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1648
    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
  1649
    retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1650
  } else if (strchr(pname, *os::path_separator()) != NULL) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1651
    int n;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1652
    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
  1653
    if (pelements == NULL) {
16672
dcubed
parents: 16609 16670
diff changeset
  1654
      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
  1655
    }
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1656
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1657
      // Really shouldn't be NULL, but check can't hurt
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1658
      if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1659
        continue; // skip the empty path values
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1660
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1661
      snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1662
      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
  1663
        retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1664
        break;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1665
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1666
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1667
    // release the storage
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1668
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1669
      if (pelements[i] != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1670
        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1671
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1672
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1673
    if (pelements != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1674
      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1675
    }
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1676
  } else {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1677
    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
  1678
    retval = true;
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1679
  }
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1680
  return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1681
}
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1682
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  1683
// check if addr is inside libjvm.so
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
bool os::address_is_in_vm(address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
  static address libjvm_base_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  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
  1689
    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
  1690
      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
  1691
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1695
  if (dladdr((void *)addr, &dlinfo) != 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
    if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
bool os::dll_address_to_function_name(address addr, char *buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
                                      int buflen, int *offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1704
  // 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
  1705
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1706
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1709
  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
  1710
    // 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
  1711
    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
  1712
      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
  1713
        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
  1714
      }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1715
      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
  1716
      return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1717
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1718
    // 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
  1719
    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
  1720
      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
  1721
                          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
  1722
        return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1723
      }
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1724
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1725
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1726
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1727
  buf[0] = '\0';
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1728
  if (offset != NULL) *offset = -1;
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1729
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
struct _address_to_library_name {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
  address addr;          // input : memory address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
  size_t  buflen;        //         size of fname
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
  char*   fname;         // output: library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
  address base;          //         library base addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
static int address_to_library_name_callback(struct dl_phdr_info *info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
                                            size_t size, void *data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  address libbase = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
  struct _address_to_library_name * d = (struct _address_to_library_name *)data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
  // iterate through all loadable segments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
  for (i = 0; i < info->dlpi_phnum; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
    address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
    if (info->dlpi_phdr[i].p_type == PT_LOAD) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
      // base address of a library is the lowest address of its loaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
      // segments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
      if (libbase == NULL || libbase > segbase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
        libbase = segbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      // see if 'addr' is within current segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
      if (segbase <= d->addr &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
          d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
        found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  // dlpi_name is NULL or empty if the ELF file is executable, return 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
  // so dll_address_to_library_name() can fall through to use dladdr() which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
  // can figure out executable name from argv[0].
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
  if (found && info->dlpi_name && info->dlpi_name[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
    d->base = libbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
    if (d->fname) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
      jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
    return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1776
bool os::dll_address_to_library_name(address addr, char* buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
                                     int buflen, int* offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1778
  // 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
  1779
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1780
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  struct _address_to_library_name data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
  // There is a bug in old glibc dladdr() implementation that it could resolve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
  // to wrong library name if the .so file has a base address != NULL. Here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  // we iterate through the program headers of all loaded libraries to find
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
  // out which library 'addr' really belongs to. This workaround can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
  // removed once the minimum requirement for glibc is moved to 2.3.x.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  data.addr = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
  data.fname = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  data.buflen = buflen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  data.base = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
  int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  if (rslt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
     // buf already contains library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
     if (offset) *offset = addr - data.base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
     return true;
18683
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 (dladdr((void*)addr, &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1801
    if (dlinfo.dli_fname != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1802
      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
  1803
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1804
    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
  1805
      *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
  1806
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1807
    return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1808
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1809
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1810
  buf[0] = '\0';
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1811
  if (offset) *offset = -1;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1812
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
  // Loads .dll/.so and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
  // in case of error it checks if .dll/.so was built for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
  // same architecture as Hotspot is running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
15926
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
// 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
  1821
// 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
  1822
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
  1823
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1824
// 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
  1825
// 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
  1826
// 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
  1827
// 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
  1828
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
  1829
 private:
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1830
  const char *_filename;
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1831
  char *_ebuf;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1832
  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
  1833
  void *_lib;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1834
 public:
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1835
  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
  1836
    _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
  1837
  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
  1838
  void doit() {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1839
    _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
  1840
    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
  1841
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1842
  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
  1843
};
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1844
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
{
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1847
  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
  1848
  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
  1849
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1850
  // 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
  1851
  // 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
  1852
  // 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
  1853
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1854
  // 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
  1855
  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
  1856
    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
  1857
    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
  1858
      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
  1859
        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
  1860
        // 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
  1861
        // 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
  1862
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1863
        // 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
  1864
        // 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
  1865
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1866
        // 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
  1867
        // 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
  1868
        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
  1869
      } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1870
        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
  1871
                "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
  1872
                "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
  1873
                "'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
  1874
                filename);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1875
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1876
        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
  1877
        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
  1878
        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
  1879
          // 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
  1880
          // 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
  1881
          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
  1882
        } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1883
          if (!LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1884
            // 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
  1885
            // 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
  1886
            // 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
  1887
            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
  1888
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1889
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1890
          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
  1891
          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
  1892
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1893
          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
  1894
          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
  1895
          if (LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1896
            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
  1897
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1898
          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
  1899
        }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1900
      }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1901
    }
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
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1904
  if (!load_attempted) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1905
    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
  1906
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1907
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
    // Successful loading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  Elf32_Ehdr elf_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  int diag_msg_max_length=ebuflen-strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
  char* diag_msg_buf=ebuf+strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  if (diag_msg_max_length==0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
    // No more space in ebuf for additional diagnostics message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
  int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
  if (file_descriptor < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
    // Can't open library, report dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  bool failed_to_read_elf_head=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
    (sizeof(elf_head)!=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
        (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  ::close(file_descriptor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  if (failed_to_read_elf_head) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
    // file i/o error - report dlerror() msg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
  typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    Elf32_Half  code;         // Actual value as defined in elf.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
    Elf32_Half  compat_class; // Compatibility of archs at VM's sense
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
    char        elf_class;    // 32 or 64 bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
    char        endianess;    // MSB or LSB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
    char*       name;         // String representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  } arch_t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  #ifndef EM_486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  #define EM_486          6               /* Intel 80486 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  static const arch_t arch_array[]={
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
    {EM_386,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    {EM_486,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    {EM_IA_64,       EM_IA_64,   ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    {EM_X86_64,      EM_X86_64,  ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    {EM_SPARC,       EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
    {EM_SPARC32PLUS, EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
    {EM_SPARCV9,     EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
    {EM_PPC,         EM_PPC,     ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1961
    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1962
    {EM_ARM,         EM_ARM,     ELFCLASS32,   ELFDATA2LSB, (char*)"ARM"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1963
    {EM_S390,        EM_S390,    ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1964
    {EM_ALPHA,       EM_ALPHA,   ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1965
    {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1966
    {EM_MIPS,        EM_MIPS,    ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1967
    {EM_PARISC,      EM_PARISC,  ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1968
    {EM_68K,         EM_68K,     ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  #if  (defined IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
    static  Elf32_Half running_arch_code=EM_386;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  #elif   (defined AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
    static  Elf32_Half running_arch_code=EM_X86_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  #elif  (defined IA64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    static  Elf32_Half running_arch_code=EM_IA_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  #elif  (defined __sparc) && (defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
    static  Elf32_Half running_arch_code=EM_SPARCV9;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
  #elif  (defined __sparc) && (!defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
    static  Elf32_Half running_arch_code=EM_SPARC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1981
  #elif  (defined __powerpc64__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
    static  Elf32_Half running_arch_code=EM_PPC64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
  #elif  (defined __powerpc__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1984
    static  Elf32_Half running_arch_code=EM_PPC;
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1985
  #elif  (defined ARM)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1986
    static  Elf32_Half running_arch_code=EM_ARM;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1987
  #elif  (defined S390)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1988
    static  Elf32_Half running_arch_code=EM_S390;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1989
  #elif  (defined ALPHA)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1990
    static  Elf32_Half running_arch_code=EM_ALPHA;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1991
  #elif  (defined MIPSEL)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1992
    static  Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1993
  #elif  (defined PARISC)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1994
    static  Elf32_Half running_arch_code=EM_PARISC;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1995
  #elif  (defined MIPS)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1996
    static  Elf32_Half running_arch_code=EM_MIPS;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1997
  #elif  (defined M68K)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1998
    static  Elf32_Half running_arch_code=EM_68K;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
  #else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
    #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
  2001
         IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
  // Identify compatability class for VM's architecture and library's architecture
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
  // Obtain string descriptions for architectures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
  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
  2008
  int running_arch_index=-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
    if (running_arch_code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
      running_arch_index    = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
    if (lib_arch.code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
      lib_arch.compat_class = arch_array[i].compat_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
      lib_arch.name         = arch_array[i].name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
  assert(running_arch_index != -1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
    "Didn't find running architecture code (running_arch_code) in arch_array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  if (running_arch_index == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
    // Even though running architecture detection failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
    // we may still continue with reporting dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
  if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2033
#ifndef S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
  if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
  }
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2038
#endif // !S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
  if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    if ( lib_arch.name!=NULL ) {
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 %s-bit .so on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
        lib_arch.name, arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
      " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
        lib_arch.code,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
        arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2056
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
  2057
  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
  2058
  if (result == NULL) {
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2059
    ::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
  2060
    ebuf[ebuflen-1] = '\0';
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2061
  }
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2062
  return result;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2063
}
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2064
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2065
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
  2066
  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
  2067
  if (LoadExecStackDllInVMThread) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2068
    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
  2069
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2070
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2071
  // 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
  2072
  // 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
  2073
  // 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
  2074
  // 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
  2075
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2076
  // 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
  2077
  // 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
  2078
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2079
  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
  2080
    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
  2081
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2082
    while (jt) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2083
      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
  2084
          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
  2085
        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
  2086
                              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
  2087
          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
  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
      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
  2091
    }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2092
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2093
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2094
  return result;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2095
}
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2096
950
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
 * 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
  2099
 * 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
  2100
 * libdl.so, so always use locking for any version of glibc.
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2101
 */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2102
void* os::dll_lookup(void* handle, const char* name) {
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2103
  pthread_mutex_lock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2104
  void* res = dlsym(handle, name);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2105
  pthread_mutex_unlock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2106
  return res;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2107
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2110
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
  2111
  int fd = ::open(filename, O_RDONLY);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  if (fd == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
     return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  char buf[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
  int bytes;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2118
  while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
    st->print_raw(buf, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2122
  ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
void os::print_dll_info(outputStream *st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
   st->print_cr("Dynamic libraries:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
   char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
   pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
   jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
   if (!_print_ascii_file(fname, st)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2136
     st->print("Can not get library information for pid = %d\n", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2137
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2138
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2139
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2140
void os::print_os_info_brief(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2141
  os::Linux::print_distro_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
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2144
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2145
  os::Linux::print_libversion_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2146
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2147
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2149
void os::print_os_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
  st->print("OS:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2152
  os::Linux::print_distro_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2153
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2154
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2155
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2156
  // Print warning if unsafe chroot environment detected
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2157
  if (unsafe_chroot_detected) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2158
    st->print("WARNING!! ");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2159
    st->print_cr(unstable_chroot_error);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2160
  }
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::Linux::print_libversion_info(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::Posix::print_rlimit_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
  os::Posix::print_load_average(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2167
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2168
  os::Linux::print_full_memory_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2169
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2170
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2171
// Try to identify popular distros.
19965
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2172
// Most Linux distributions have a /etc/XXX-release file, which contains
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2173
// the OS version string. Newer Linux distributions have a /etc/lsb-release
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2174
// file that also contains the OS version string. Some have more than one
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2175
// /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2176
// /etc/redhat-release.), so the order is important.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2177
// Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2178
// their own specific XXX-release file as well as a redhat-release file.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2179
// Because of this the XXX-release file needs to be searched for before the
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2180
// redhat-release file.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2181
// Since Red Hat has a lsb-release file that is not very descriptive the
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2182
// search for redhat-release needs to be before lsb-release.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2183
// Since the lsb-release file is the new standard it needs to be searched
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2184
// before the older style release files.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2185
// Searching system-release (Red Hat) and os-release (other Linuxes) are a
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2186
// next to last resort.  The os-release file is a new standard that contains
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2187
// distribution information and the system-release file seems to be an old
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2188
// standard that has been replaced by the lsb-release and os-release files.
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2189
// Searching for the debian_version file is the last resort.  It contains
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2190
// an informative string like "6.0.6" or "wheezy/sid". Because of this
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2191
// "Debian " is printed before the contents of the debian_version file.
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2192
void os::Linux::print_distro_info(outputStream* st) {
19965
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2193
   if (!_print_ascii_file("/etc/oracle-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2194
       !_print_ascii_file("/etc/mandriva-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2195
       !_print_ascii_file("/etc/mandrake-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2196
       !_print_ascii_file("/etc/sun-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2197
       !_print_ascii_file("/etc/redhat-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2198
       !_print_ascii_file("/etc/lsb-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2199
       !_print_ascii_file("/etc/SuSE-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2200
       !_print_ascii_file("/etc/turbolinux-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2201
       !_print_ascii_file("/etc/gentoo-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2202
       !_print_ascii_file("/etc/ltib-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2203
       !_print_ascii_file("/etc/angstrom-version", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2204
       !_print_ascii_file("/etc/system-release", st) &&
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2205
       !_print_ascii_file("/etc/os-release", st)) {
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2206
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2207
       if (file_exists("/etc/debian_version")) {
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2208
         st->print("Debian ");
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2209
         _print_ascii_file("/etc/debian_version", st);
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2210
       } else {
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2211
         st->print("Linux");
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2212
       }
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2213
   }
7d9d20ec275b 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 19964
diff changeset
  2214
   st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2215
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2216
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2217
void os::Linux::print_libversion_info(outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
  // libc, pthread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
  st->print("libc:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
  st->print(os::Linux::glibc_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
  st->print(os::Linux::libpthread_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
  if (os::Linux::is_LinuxThreads()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
     st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
  st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2226
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2227
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2228
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
  2229
   st->print("\n/proc/meminfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2230
   _print_ascii_file("/proc/meminfo", st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2231
   st->cr();
10023
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2232
}
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2233
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
void os::print_memory_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
  st->print("Memory:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
  st->print(" %dk page", os::vm_page_size()>>10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
  st->print(", physical " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
            os::physical_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
            os::available_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
  st->print(", swap " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
            ((jlong)si.totalswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
            ((jlong)si.freeswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2254
void os::pd_print_cpu_info(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2255
  st->print("\n/proc/cpuinfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2256
  if (!_print_ascii_file("/proc/cpuinfo", st)) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2257
    st->print("  <Not Available>");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2258
  }
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2259
  st->cr();
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2260
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2261
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
// Taken from /usr/include/bits/siginfo.h  Supposed to be architecture specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
// but they're the same for all the linux arch that we support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
// and they're the same for solaris but there's no common place to put this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
                          "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
                          "ILL_COPROC", "ILL_BADSTK" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
                          "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
                          "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
void os::print_siginfo(outputStream* st, void* siginfo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  st->print("siginfo:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
  const int buflen = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  char buf[buflen];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
  siginfo_t *si = (siginfo_t*)siginfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
  if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
    st->print("si_errno=%s", buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
    st->print("si_errno=%d", si->si_errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
  const int c = si->si_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
  assert(c > 0, "unexpected si_code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
  switch (si->si_signo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
    st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
    st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
    st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
    st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
    st->print(", si_code=%d", si->si_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
    // no si_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
  if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
      UseSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
    FileMapInfo* mapinfo = FileMapInfo::current_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
    if (mapinfo->is_in_shared_space(si->si_addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
      st->print("\n\nError accessing class data sharing archive."   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
                " Mapped file inaccessible during execution, "      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
                " possible disk/network problem.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
                                 char* buf, size_t buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
  st->print_cr("Signal Handlers:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
  print_signal_handler(st, SIGSEGV, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
  print_signal_handler(st, SIGBUS , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
  print_signal_handler(st, SIGFPE , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
  print_signal_handler(st, SIGPIPE, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
  print_signal_handler(st, SIGXFSZ, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
  print_signal_handler(st, SIGILL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
  print_signal_handler(st, SR_signum, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
  print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
  print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
  print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
  print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
static char saved_jvm_path[MAXPATHLEN] = {0};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2347
// Find the full path to the current module, libjvm.so
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2348
void os::jvm_path(char *buf, jint buflen) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
  // Error checking.
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2350
  if (buflen < MAXPATHLEN) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
    assert(false, "must use a large-enough buffer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
    buf[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
  // Lazy resolve the path to current module.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
  if (saved_jvm_path[0] != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
    strcpy(buf, saved_jvm_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
  char dli_fname[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
  bool ret = dll_address_to_library_name(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
                CAST_FROM_FN_PTR(address, os::jvm_path),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
                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
  2365
  assert(ret, "cannot locate libjvm");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2366
  char *rp = NULL;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2367
  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
  2368
    rp = realpath(dli_fname, buf);
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2369
  }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2370
  if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2371
    return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
8476
7e34c2d4cf9b 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 8119
diff changeset
  2373
  if (Arguments::created_by_gamma_launcher()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
    // Support for the gamma launcher.  Typical value for buf is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
    // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
    // the right place in the string, then assume we are installed in a JDK and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
    // we're done.  Otherwise, check for a JAVA_HOME environment variable and fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
    // up the path so it looks like libjvm.so is installed there (append a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
    // fake suffix hotspot/libjvm.so).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
    const char *p = buf + strlen(buf) - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
    for (int count = 0; p > buf && count < 5; ++count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
      for (--p; p > buf && *p != '/'; --p)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
        /* empty */ ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
    if (strncmp(p, "/jre/lib/", 9) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
      // Look for JAVA_HOME in the environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
      char* java_home_var = ::getenv("JAVA_HOME");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
      if (java_home_var != NULL && java_home_var[0] != 0) {
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2390
        char* jrelib_p;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2391
        int len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2392
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2393
        // Check the current module name "libjvm.so".
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
        p = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
        assert(strstr(p, "/libjvm") == p, "invalid library name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2397
        rp = realpath(java_home_var, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2398
        if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2399
          return;
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2400
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2401
        // determine if this is a legacy image or modules image
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2402
        // modules image doesn't have "jre" subdirectory
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2403
        len = strlen(buf);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2404
        jrelib_p = buf + len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2405
        snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2406
        if (0 != access(buf, F_OK)) {
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2407
          snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2408
        }
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2409
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
        if (0 == access(buf, F_OK)) {
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2411
          // Use current module name "libjvm.so"
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2412
          len = strlen(buf);
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2413
          snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
          // Go back to path of .so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2416
          rp = realpath(dli_fname, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2417
          if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2418
            return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
  strcpy(saved_jvm_path, buf);
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::print_jni_name_prefix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  // no prefix required, not even "_"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
  // no suffix required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
// sun.misc.Signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
static volatile jint sigint_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
static void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
UserHandler(int sig, void *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
  // 4511530 - sem_post is serialized and handled by the manager thread. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
  // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
  // don't want to flood the manager thread with sem_post requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
  if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
  // Ctrl-C is pressed during error reporting, likely because the error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
  // handler fails to abort. Let VM die immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
  if (sig == SIGINT && is_error_reported()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
     os::die();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
  os::signal_notify(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
void* os::user_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
  return CAST_FROM_FN_PTR(void*, UserHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2461
class Semaphore : public StackObj {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2462
  public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2463
    Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2464
    ~Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2465
    void signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2466
    void wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2467
    bool trywait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2468
    bool timedwait(unsigned int sec, int nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2469
  private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2470
    sem_t _semaphore;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2471
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2472
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2473
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2474
Semaphore::Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2475
  sem_init(&_semaphore, 0, 0);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2476
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2477
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2478
Semaphore::~Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2479
  sem_destroy(&_semaphore);
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
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2482
void Semaphore::signal() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2483
  sem_post(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2484
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2485
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2486
void Semaphore::wait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2487
  sem_wait(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2488
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2489
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2490
bool Semaphore::trywait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2491
  return sem_trywait(&_semaphore) == 0;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2492
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2493
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2494
bool Semaphore::timedwait(unsigned int sec, int nsec) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2495
  struct timespec ts;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2496
  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2497
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2498
  while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2499
    int result = sem_timedwait(&_semaphore, &ts);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2500
    if (result == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2501
      return true;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2502
    } else if (errno == EINTR) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2503
      continue;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2504
    } else if (errno == ETIMEDOUT) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2505
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2506
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2507
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2508
    }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2509
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2510
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2511
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
  typedef void (*sa_handler_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
  typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
void* os::signal(int signal_number, void* handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
  struct sigaction sigAct, oldSigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
  sigAct.sa_flags   = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
  sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
  if (sigaction(signal_number, &sigAct, &oldSigAct)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
    // -1 means registration failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
    return (void *)-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
  return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
void os::signal_raise(int signal_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  ::raise(signal_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
 * The following code is moved from os.cpp for making this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
 * code platform specific, which it is by its very nature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
// Will be modified when max signal is changed to be dynamic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
int os::sigexitnum_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
  return NSIG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
// a counter for each possible signal value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
static volatile jint pending_signals[NSIG+1] = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
// Linux(POSIX) specific hand shaking semaphore.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
static sem_t sig_sem;
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2551
static Semaphore sr_semaphore;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
void os::signal_init_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
  // Initialize signal structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
  ::memset((void*)pending_signals, 0, sizeof(pending_signals));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
  // Initialize signal semaphore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
  ::sem_init(&sig_sem, 0, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
void os::signal_notify(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
  Atomic::inc(&pending_signals[sig]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
  ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
static int check_pending_signals(bool wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
  Atomic::store(0, &sigint_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
    for (int i = 0; i < NSIG + 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
      jint n = pending_signals[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
        return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
    if (!wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
      return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
    JavaThread *thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
    ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
    bool threadIsSuspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
      thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
      ::sem_wait(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
      // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
      if (threadIsSuspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
        // The semaphore has been incremented, but while we were waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
        // another thread suspended us. We don't want to continue running
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
        // while suspended because that would surprise the thread that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
        // suspended us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
        ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
        thread->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
    } while (threadIsSuspended);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
int os::signal_lookup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
  return check_pending_signals(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
int os::signal_wait() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
  return check_pending_signals(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
// Virtual Memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
int os::vm_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
  // Seems redundant as all get out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
// Solaris allocates memory by pages.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
int os::vm_allocation_granularity() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
// Rationale behind this function:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
//  current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
//  mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
//  samples for JITted code. Here we create private executable mapping over the code cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
//  and then we can use standard (well, almost, as mapping can change) way to provide
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
//  info for the reporting script by storing timestamp and location of symbol
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
void linux_wrap_code(char* base, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
  static volatile jint cnt = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
  if (!UseOprofile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
5410
c4b979417733 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 5237
diff changeset
  2640
  char buf[PATH_MAX+1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
  int num = Atomic::add(1, &cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5090
diff changeset
  2643
  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
  2644
           os::get_temp_directory(), os::current_process_id(), num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
  unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2647
  int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
  if (fd != -1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2650
    off_t rv = ::lseek(fd, size-2, SEEK_SET);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
    if (rv != (off_t)-1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2652
      if (::write(fd, "", 1) == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
        mmap(base, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
             PROT_READ|PROT_WRITE|PROT_EXEC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
             MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2658
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2663
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
  2664
  // 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
  2665
  // 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
  2666
  // 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
  2667
  // 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
  2668
  // 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
  2669
  switch (err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2670
  case EBADF:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2671
  case EINVAL:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2672
  case ENOTSUP:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2673
    // 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
  2674
    return true;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2675
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2676
  default:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2677
    // 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
  2678
    // 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
  2679
    // 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
  2680
    // 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
  2681
    // same memory mapped.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2682
    return false;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2683
  }
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
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
  2687
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2688
  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
  2689
          ", %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
  2690
          strerror(err), err);
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
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
  2694
                                    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
  2695
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2696
  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
  2697
          ", " 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
  2698
          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
  2699
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2700
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
// NOTE: Linux kernel does not really reserve the pages for us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
//       All it does is to check if there are enough free pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
//       left at the time of mmap(). This could be a potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
//       problem.
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2705
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
  2706
  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  2707
  uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
                                   MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2709
  if (res != (uintptr_t) MAP_FAILED) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2710
    if (UseNUMAInterleaving) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2711
      numa_make_global(addr, size);
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2712
    }
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2713
    return 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2714
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2715
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2716
  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
  2717
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2718
  if (!recoverable_mmap_error(err)) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2719
    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
  2720
    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
  2721
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2722
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2723
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2724
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2725
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2726
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
  2727
  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
  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
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
  2731
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2732
  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
  2733
  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
  2734
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2735
    // 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
  2736
    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
  2737
    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
  2738
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2741
// 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
  2742
#ifndef MAP_HUGETLB
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2743
#define MAP_HUGETLB 0x40000
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2744
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2745
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2746
// 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
  2747
#ifndef MADV_HUGEPAGE
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2748
#define MADV_HUGEPAGE 14
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2749
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2750
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2751
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
  2752
                                  size_t alignment_hint, bool exec) {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  2753
  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
  2754
  if (err == 0) {
10522
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2755
    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
  2756
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2757
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2758
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2759
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2760
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
  2761
                          bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2762
  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
  2763
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2764
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2765
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
  2766
                                  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
  2767
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2768
  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
  2769
  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
  2770
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2771
    // 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
  2772
    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
  2773
    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
  2774
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2777
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
  2778
  if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2779
    // 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
  2780
    // 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
  2781
    ::madvise(addr, bytes, MADV_HUGEPAGE);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2782
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2783
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2784
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2785
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
  2786
  // 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
  2787
  // 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
  2788
  // 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
  2789
  // 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
  2790
  // allow that in any case.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  2791
  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
  2792
    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
  2793
  }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2794
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2795
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2796
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
  2797
  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
  2798
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2799
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2800
// 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
  2801
// bind policy to MPOL_PREFERRED for the current thread.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2802
#define USE_MPOL_PREFERRED 0
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2803
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2804
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
  2805
  // 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
  2806
  // 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
  2807
  // 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
  2808
  // 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
  2809
  // 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
  2810
  // 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
  2811
  // free large pages.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2812
  Linux::numa_set_bind_policy(USE_MPOL_PREFERRED);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2813
  Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2814
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2815
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2816
bool os::numa_topology_changed()   { return false; }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2817
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2818
size_t os::numa_get_groups_num() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2819
  int max_node = Linux::numa_max_node();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2820
  return max_node > 0 ? max_node + 1 : 1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2821
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2822
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2823
int os::numa_get_group_id() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2824
  int cpu_id = Linux::sched_getcpu();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2825
  if (cpu_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2826
    int lgrp_id = Linux::get_node_by_cpu(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2827
    if (lgrp_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2828
      return lgrp_id;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2829
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2834
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
  2835
  for (size_t i = 0; i < size; i++) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2836
    ids[i] = i;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2837
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2838
  return size;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2839
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2840
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
bool os::get_page_info(char *start, page_info* info) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2849
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2850
int os::Linux::sched_getcpu_syscall(void) {
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2851
  unsigned int cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2852
  int retval = -1;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2853
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2854
#if defined(IA32)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2855
# ifndef SYS_getcpu
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2856
# define SYS_getcpu 318
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2857
# endif
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2858
  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2859
#elif defined(AMD64)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2860
// 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
  2861
// to be able to compile on old linuxes.
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2862
# define __NR_vgetcpu 2
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2863
# define VSYSCALL_START (-10UL << 20)
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2864
# define VSYSCALL_SIZE 1024
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2865
# 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
  2866
  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
  2867
  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
  2868
  retval = vgetcpu(&cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2869
#endif
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2870
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2871
  return (retval == -1) ? retval : cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2872
}
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2873
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2874
// Something to do with the numa-aware allocator needs these symbols
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2875
extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2876
extern "C" JNIEXPORT void numa_error(char *where) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2877
extern "C" JNIEXPORT int fork1() { return fork(); }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2878
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2879
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2880
// 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
  2881
// 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
  2882
// 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
  2883
// we should use the base version.
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2884
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
  2885
  void *f = dlvsym(handle, name, "libnuma_1.1");
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2886
  if (f == NULL) {
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2887
    f = dlsym(handle, name);
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2888
  }
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2889
  return f;
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2890
}
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2891
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2892
bool os::Linux::libnuma_init() {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2893
  // sched_getcpu() should be in libc.
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2894
  set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2895
                                  dlsym(RTLD_DEFAULT, "sched_getcpu")));
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2896
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2897
  // If it's not, try a direct syscall.
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2898
  if (sched_getcpu() == -1)
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2899
    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
  2900
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2901
  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
  2902
    void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2903
    if (handle != NULL) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2904
      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
  2905
                                           libnuma_dlsym(handle, "numa_node_to_cpus")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2906
      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
  2907
                                       libnuma_dlsym(handle, "numa_max_node")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2908
      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
  2909
                                        libnuma_dlsym(handle, "numa_available")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2910
      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
  2911
                                            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
  2912
      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
  2913
                                            libnuma_dlsym(handle, "numa_interleave_memory")));
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2914
      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
  2915
                                            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
  2916
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2917
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2918
      if (numa_available() != -1) {
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2919
        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
  2920
        // Create a cpu -> node mapping
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2921
        _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
  2922
        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
  2923
        return true;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2924
      }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2925
    }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2926
  }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2927
  return false;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2928
}
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
// 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
  2931
// The table is later used in get_node_by_cpu().
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2932
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
  2933
  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
  2934
                              // 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
  2935
                              // 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
  2936
                              // 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
  2937
                              // 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
  2938
                              // 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
  2939
                              // in the library.
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2940
  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
  2941
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2942
  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
  2943
  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
  2944
  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
  2945
    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
  2946
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2947
  cpu_to_node()->clear();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2948
  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
  2949
  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
  2950
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2951
  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
  2952
  for (size_t i = 0; i < node_num; i++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2953
    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
  2954
      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
  2955
        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
  2956
          for (size_t k = 0; k < BitsPerCLong; k++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2957
            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
  2958
              cpu_to_node()->at_put(j * BitsPerCLong + k, i);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2959
            }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2960
          }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2961
        }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2962
      }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2963
    }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2964
  }
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2965
  FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2966
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2967
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2968
int os::Linux::get_node_by_cpu(int cpu_id) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2969
  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
  2970
    return cpu_to_node()->at(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2971
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2972
  return -1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2973
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2974
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2975
GrowableArray<int>* os::Linux::_cpu_to_node;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2976
os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2977
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
  2978
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
  2979
os::Linux::numa_available_func_t os::Linux::_numa_available;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2980
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
  2981
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
  2982
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
  2983
unsigned long* os::Linux::_numa_all_nodes;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2984
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2985
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
  2986
  uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2987
                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2988
  return res  != (uintptr_t) MAP_FAILED;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2991
static
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2992
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
  2993
  address nbot = bottom;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2994
  address ntop = bottom + size;
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
  size_t page_sz = os::vm_page_size();
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  2997
  unsigned pages = size / 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
  unsigned char vec[1];
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3000
  unsigned imin = 1, imax = pages + 1, imid;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3001
  int mincore_return_value;
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
  while (imin < imax) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3004
    imid = (imax + imin) / 2;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3005
    nbot = ntop - (imid * page_sz);
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
    // 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
  3008
    // 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
  3009
    // 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
  3010
    // it returns -1,ENOMEM
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3011
    mincore_return_value = mincore(nbot, page_sz, vec);
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3012
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3013
    if (mincore_return_value == -1) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3014
      // Page is not mapped go up
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3015
      // to find first mapped page
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3016
      if (errno != EAGAIN) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3017
        assert(errno == ENOMEM, "Unexpected mincore errno");
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3018
        imax = imid;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3019
      }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3020
    } else {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3021
      // Page is mapped go down
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3022
      // to find first not mapped page
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3023
      imin = imid + 1;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3024
    }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3025
  }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3026
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3027
  nbot = nbot + page_sz;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3028
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3029
  // 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
  3030
  if (mincore_return_value == -1) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3031
    nbot = nbot + page_sz;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3032
  }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3033
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3034
  return nbot;
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3035
}
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3036
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3037
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3038
// 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
  3039
// 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
  3040
// 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
  3041
// 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
  3042
// 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
  3043
// 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
  3044
//
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3045
// 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
  3046
// 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
  3047
// 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
  3048
// 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
  3049
// 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
  3050
// create_stack_guard_pages() is called.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3051
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3052
// 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
  3053
// 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
  3054
// 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
  3055
// 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
  3056
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3057
// 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
  3058
// 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
  3059
// 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
  3060
// 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
  3061
// mapping. This only affects the main/initial thread
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3062
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3063
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
  3064
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3065
  if (os::Linux::is_initial_thread()) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3066
    // 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
  3067
    // 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
  3068
    // we don't need to do anything special.
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3069
    // Check it first, before calling heavy function.
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3070
    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
  3071
    unsigned char vec[1];
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3072
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3073
    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
  3074
      // 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
  3075
      stack_extent = (uintptr_t) get_stack_commited_bottom(
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3076
                                    os::Linux::initial_thread_stack_bottom(),
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3077
                                    (size_t)addr - stack_extent);
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3078
    }
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3079
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3080
    if (stack_extent < (uintptr_t)addr) {
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3081
      ::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
  3082
    }
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3083
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3084
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3085
  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
  3086
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3087
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3088
// 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
  3089
// 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
  3090
// 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
  3091
// 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
  3092
// 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
  3093
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3094
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
  3095
  uintptr_t stack_extent, stack_base;
19694
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3096
84bcddefd0d7 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 19546
diff changeset
  3097
  if (os::Linux::is_initial_thread()) {
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3098
    return ::munmap(addr, size) == 0;
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3099
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3100
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3101
  return os::uncommit_memory(addr, size);
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3102
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3103
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
static address _highest_vm_reserved_address = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
// at 'requested_addr'. If there are existing memory mappings at the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
// location, however, they will be overwritten. If 'fixed' is false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
// 'requested_addr' is only treated as a hint, the return value may or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
// may not start from the requested address. Unlike Linux mmap(), this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
// function returns NULL to indicate failure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
  char * addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
  int flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
  flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
  if (fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
    assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
17083
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3122
  // 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
  3123
  // touch an uncommitted page. Otherwise, the read/write might
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3124
  // 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
  3125
  addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
                       flags, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
  if (addr != MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
    // anon_mmap() should only get called during VM initialization,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
    // don't need lock (actually we can skip locking even it can be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
    // from multiple threads, because _highest_vm_reserved_address is just a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
    // hint about the upper limit of non-stack memory regions.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    if ((address)addr + bytes > _highest_vm_reserved_address) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
      _highest_vm_reserved_address = (address)addr + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  return addr == MAP_FAILED ? NULL : addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
// Don't update _highest_vm_reserved_address, because there might be memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
// regions above addr + size. If so, releasing a memory region only creates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
// a hole in the address space, it doesn't help prevent heap-stack collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
static int anon_munmap(char * addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
  return ::munmap(addr, size) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3149
char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
                         size_t alignment_hint) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
  return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3154
bool os::pd_release_memory(char* addr, size_t size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
  return anon_munmap(addr, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
static address highest_vm_reserved_address() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
  return _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
static bool linux_mprotect(char* addr, size_t size, int prot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
  // Linux wants the mprotect address argument to be page aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
  char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
  // According to SUSv3, mprotect() should only be used with mappings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
  // established by mmap(), and mmap() always maps whole pages. Unaligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
  // 'addr' likely indicates problem in the VM (e.g. trying to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
  // protection of malloc'ed or statically allocated memory). Check the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
  // caller if you hit this assert.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
  assert(addr == bottom, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
  return ::mprotect(bottom, size, prot) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3177
// Set protections specified
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3178
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
  3179
                        bool is_committed) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3180
  unsigned int p = 0;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3181
  switch (prot) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3182
  case MEM_PROT_NONE: p = PROT_NONE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3183
  case MEM_PROT_READ: p = PROT_READ; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3184
  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3185
  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
  3186
  default:
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3187
    ShouldNotReachHere();
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3188
  }
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3189
  // is_committed is unused.
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3190
  return linux_mprotect(addr, bytes, p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
bool os::guard_memory(char* addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
  return linux_mprotect(addr, size, PROT_NONE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
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
  3198
  return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3201
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
  3202
  bool result = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3203
  void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3204
                 MAP_ANONYMOUS|MAP_PRIVATE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3205
                 -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3206
  if (p != MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3207
    void *aligned_p = align_ptr_up(p, page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3208
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3209
    result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3210
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3211
    munmap(p, page_size * 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3212
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3213
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3214
  if (warn && !result) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3215
    warning("TransparentHugePages is not supported by the operating system.");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3216
  }
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
  return result;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3219
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3220
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3221
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
  3222
  bool result = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3223
  void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3224
                 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3225
                 -1, 0);
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3226
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3227
  if (p != MAP_FAILED) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3228
    // 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
  3229
    FILE *fp = fopen("/proc/self/maps", "r");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3230
    if (fp) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3231
      while (!feof(fp)) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3232
        char chars[257];
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3233
        long x = 0;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3234
        if (fgets(chars, sizeof(chars), fp)) {
9625
822a93889b58 7043564: compile warning and copyright fixes
iveresov
parents: 9419
diff changeset
  3235
          if (sscanf(chars, "%lx-%*x", &x) == 1
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3236
              && x == (long)p) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3237
            if (strstr (chars, "hugepage")) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3238
              result = true;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3239
              break;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3240
            }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3241
          }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3242
        }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3243
      }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3244
      fclose(fp);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3245
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3246
    munmap(p, page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3247
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3248
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3249
  if (warn && !result) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3250
    warning("HugeTLBFS is not supported by the operating system.");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3251
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3252
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3253
  return result;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3254
}
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3255
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3256
/*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3257
* 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
  3258
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3259
* From the coredump_filter documentation:
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3260
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3261
* - (bit 0) anonymous private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3262
* - (bit 1) anonymous shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3263
* - (bit 2) file-backed private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3264
* - (bit 3) file-backed shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3265
* - (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
  3266
*           effective only if the bit 2 is cleared)
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3267
* - (bit 5) hugetlb private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3268
* - (bit 6) hugetlb shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3269
*/
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3270
static void set_coredump_filter(void) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3271
  FILE *f;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3272
  long cdm;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3273
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3274
  if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3275
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3276
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3277
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3278
  if (fscanf(f, "%lx", &cdm) != 1) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3279
    fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3280
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3281
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3282
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3283
  rewind(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3284
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3285
  if ((cdm & LARGEPAGES_BIT) == 0) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3286
    cdm |= LARGEPAGES_BIT;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3287
    fprintf(f, "%#lx", cdm);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3288
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3289
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3290
  fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3291
}
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3292
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
// Large page support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
static size_t _large_page_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3297
size_t os::Linux::find_large_page_size() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3298
  size_t large_page_size = 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3299
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3300
  // 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
  3301
  // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3302
  // 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
  3303
  // page as large as 256M.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3304
  //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3305
  // 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
  3306
  // for a line with the following format:
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3307
  //    Hugepagesize:     2048 kB
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 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
  3310
  // 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
  3311
  // the processor.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3313
#ifndef ZERO
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3314
  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
  3315
                     ARM_ONLY(2 * M) PPC_ONLY(4 * M);
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3316
#endif // ZERO
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3318
  FILE *fp = fopen("/proc/meminfo", "r");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3319
  if (fp) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3320
    while (!feof(fp)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3321
      int x = 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3322
      char buf[16];
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3323
      if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3324
        if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3325
          large_page_size = x * K;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3326
          break;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3327
        }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3328
      } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3329
        // skip to next line
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3330
        for (;;) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3331
          int ch = fgetc(fp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3332
          if (ch == EOF || ch == (int)'\n') break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3336
    fclose(fp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3337
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3338
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3339
  if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3340
    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
  3341
        SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size),
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3342
        proper_unit_for_byte_size(large_page_size));
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3343
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3344
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3345
  return large_page_size;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3346
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3347
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3348
size_t os::Linux::setup_large_page_size() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3349
  _large_page_size = Linux::find_large_page_size();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
  const size_t default_page_size = (size_t)Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
  if (_large_page_size > default_page_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
    _page_sizes[0] = _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
    _page_sizes[1] = default_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
    _page_sizes[2] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
  }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3356
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3357
  return _large_page_size;
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
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3360
bool os::Linux::setup_large_page_type(size_t page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3361
  if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3362
      FLAG_IS_DEFAULT(UseSHM) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3363
      FLAG_IS_DEFAULT(UseTransparentHugePages)) {
20400
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3364
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3365
    // The type of large pages has not been specified by the user.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3366
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3367
    // Try UseHugeTLBFS and then UseSHM.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3368
    UseHugeTLBFS = UseSHM = true;
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3369
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3370
    // Don't try UseTransparentHugePages since there are known
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3371
    // performance issues with it turned on. This might change in the future.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3372
    UseTransparentHugePages = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3373
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3374
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3375
  if (UseTransparentHugePages) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3376
    bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3377
    if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3378
      UseHugeTLBFS = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3379
      UseSHM = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3380
      return true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3381
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3382
    UseTransparentHugePages = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3383
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3384
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3385
  if (UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3386
    bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3387
    if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3388
      UseSHM = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3389
      return true;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3390
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3391
    UseHugeTLBFS = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3392
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3393
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3394
  return UseSHM;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3395
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3396
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3397
void os::large_page_init() {
20400
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3398
  if (!UseLargePages &&
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3399
      !UseTransparentHugePages &&
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3400
      !UseHugeTLBFS &&
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3401
      !UseSHM) {
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3402
    // Not using large pages.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3403
    return;
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3404
  }
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3405
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3406
  if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) {
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3407
    // The user explicitly turned off large pages.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3408
    // Ignore the rest of the large pages flags.
1c658ebcb3c1 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 20005
diff changeset
  3409
    UseTransparentHugePages = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3410
    UseHugeTLBFS = false;
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3411
    UseSHM = false;
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3412
    return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3413
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3414
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3415
  size_t large_page_size = Linux::setup_large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3416
  UseLargePages          = Linux::setup_large_page_type(large_page_size);
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3417
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3418
  set_coredump_filter();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
#ifndef SHM_HUGETLB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
#define SHM_HUGETLB 04000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3425
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
  3426
  // "exec" is passed in but not used.  Creating the shared image for
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3427
  // 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
  3428
  assert(UseLargePages && UseSHM, "only for SHM large pages");
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3429
  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3430
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3431
  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
  3432
    return NULL; // Fallback to small pages.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3433
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
  key_t key = IPC_PRIVATE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  char *addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  bool warn_on_failure = UseLargePages &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
                        (!FLAG_IS_DEFAULT(UseLargePages) ||
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3440
                         !FLAG_IS_DEFAULT(UseSHM) ||
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
                         !FLAG_IS_DEFAULT(LargePageSizeInBytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
                        );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  char msg[128];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
  // Create a large shared memory region to attach to based on size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  // Currently, size is the total size of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
  int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  if (shmid == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
     // Possible reasons for shmget failure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
     // 1. shmmax is too small for Java heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
     //    > check shmmax value: cat /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
     //    > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
     // 2. not enough large page memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
     //    > check available large pages: cat /proc/meminfo
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
     //    > increase amount of large pages:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
     //          echo new_value > /proc/sys/vm/nr_hugepages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
     //      Note 1: different Linux may use different name for this property,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
     //            e.g. on Redhat AS-3 it is "hugetlb_pool".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
     //      Note 2: it's possible there's enough physical memory available but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
     //            they are so fragmented after a long run that they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
     //            coalesce into large pages. Try to reserve large pages when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
     //            the system is still "fresh".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
       jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
  // attach to the region
5532
34c4ef11dbed 6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents: 5413
diff changeset
  3471
  addr = (char*)shmat(shmid, req_addr, 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
  int err = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
  // Remove shmid. If shmat() is successful, the actual shared memory segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
  // will be deleted when it's detached by shmdt() or when the process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
  // terminates. If shmat() is not successful this will remove the shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
  // segment immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
  shmctl(shmid, IPC_RMID, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
  if ((intptr_t)addr == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3488
  return addr;
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
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3491
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
  3492
  assert(error == ENOMEM, "Only expect to fail if no memory is available");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3493
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3494
  bool warn_on_failure = UseLargePages &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3495
      (!FLAG_IS_DEFAULT(UseLargePages) ||
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3496
       !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3497
       !FLAG_IS_DEFAULT(LargePageSizeInBytes));
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3498
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3499
  if (warn_on_failure) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3500
    char msg[128];
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3501
    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
  3502
        PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3503
    warning(msg);
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
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3507
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
  3508
  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3509
  assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3510
  assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
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
  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
  3513
  char* addr = (char*)::mmap(req_addr, bytes, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3514
                             MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3515
                             -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3516
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3517
  if (addr == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3518
    warn_on_large_pages_failure(req_addr, bytes, errno);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3519
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3520
  }
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
  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
  3523
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
  return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3527
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
  3528
  size_t large_page_size = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3529
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3530
  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
  3531
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3532
  // Allocate small pages.
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
  char* start;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3535
  if (req_addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3536
    assert(is_ptr_aligned(req_addr, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3537
    assert(is_size_aligned(bytes, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3538
    start = os::reserve_memory(bytes, req_addr);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3539
    assert(start == NULL || start == req_addr, "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3540
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3541
    start = os::reserve_memory_aligned(bytes, alignment);
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
  if (start == NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3545
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3546
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3547
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3548
  assert(is_ptr_aligned(start, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3549
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3550
  // os::reserve_memory_special will record this memory area.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3551
  // Need to release it here to prevent overlapping reservations.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3552
  MemTracker::record_virtual_memory_release((address)start, bytes);
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
  char* end = start + bytes;
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
  // 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
  3557
  char* lp_start = (char*)align_ptr_up(start, large_page_size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3558
  char* lp_end   = (char*)align_ptr_down(end, large_page_size);
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
  size_t lp_bytes = lp_end - lp_start;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3561
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3562
  assert(is_size_aligned(lp_bytes, large_page_size), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3563
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3564
  if (lp_bytes == 0) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3565
    // 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
  3566
    // Fall back to allocate a non-special area.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3567
    ::munmap(start, end - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3568
    return NULL;
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
  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
  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
  void* result;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3575
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3576
  if (start != lp_start) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3577
    result = ::mmap(start, lp_start - start, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3578
                    MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3579
                    -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3580
    if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3581
      ::munmap(lp_start, end - lp_start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3582
      return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3583
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3584
  }
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
  result = ::mmap(lp_start, lp_bytes, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3587
                  MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3588
                  -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3589
  if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3590
    warn_on_large_pages_failure(req_addr, bytes, errno);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3591
    // 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
  3592
    // have regions before and after with small pages. Release these regions.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3593
    //
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3594
    // |  mapped  |  unmapped  |  mapped  |
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3595
    // ^          ^            ^          ^
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3596
    // start      lp_start     lp_end     end
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
    ::munmap(start, lp_start - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3599
    ::munmap(lp_end, end - lp_end);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3600
    return NULL;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3601
  }
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
  if (lp_end != end) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3604
      result = ::mmap(lp_end, end - lp_end, prot,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3605
                      MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3606
                      -1, 0);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3607
    if (result == MAP_FAILED) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3608
      ::munmap(start, lp_end - start);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3609
      return NULL;
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
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3612
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3613
  return start;
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
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
  3617
  assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3618
  assert(is_ptr_aligned(req_addr, alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3619
  assert(is_power_of_2(alignment), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3620
  assert(is_power_of_2(os::large_page_size()), "Must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3621
  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
  3622
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3623
  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
  3624
    return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3625
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3626
    return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3627
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3628
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3629
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3630
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
  3631
  assert(UseLargePages, "only for large pages");
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
  char* addr;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3634
  if (UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3635
    addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3636
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3637
    assert(UseHugeTLBFS, "must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3638
    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
  3639
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3640
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3641
  if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3642
    if (UseNUMAInterleaving) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3643
      numa_make_global(addr, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3644
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3645
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3646
    // The memory is committed
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3647
    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
  3648
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3649
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3650
  return addr;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3651
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3652
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3653
bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3654
  // 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
  3655
  return shmdt(base) == 0;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3656
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3657
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3658
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
  3659
  return pd_release_memory(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3660
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3661
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
bool os::release_memory_special(char* base, size_t bytes) {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3663
  assert(UseLargePages, "only for large pages");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3664
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3665
  MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3666
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3667
  bool res;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3668
  if (UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3669
    res = os::Linux::release_memory_special_shm(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3670
  } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3671
    assert(UseHugeTLBFS, "must be");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3672
    res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3673
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3674
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3675
  if (res) {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3676
    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
  3677
  } else {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3678
    tkr.discard();
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3679
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3680
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3681
  return res;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
size_t os::large_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  return _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3688
// 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
  3689
// memory.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3690
// HugeTLBFS allows application to commit large page memory on demand.
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3691
// However, when committing memory with HugeTLBFS fails, the region
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3692
// that was supposed to be committed will lose the old reservation
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3693
// and allow other threads to steal that memory region. Because of this
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3694
// behavior we can't commit HugeTLBFS memory.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
bool os::can_commit_large_page_memory() {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3696
  return UseTransparentHugePages;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3699
bool os::can_execute_large_page_memory() {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  3700
  return UseTransparentHugePages || UseHugeTLBFS;
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3701
}
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3702
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
// Reserve memory at an arbitrary address, only if that area is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
// available (and not reserved for something else).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3706
char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
  const int max_tries = 10;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
  char* base[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
  size_t size[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
  const size_t gap = 0x000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
  // Assert only that the size is a multiple of the page size, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
  // that's all that mmap requires, and since that's all we really know
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
  // about at this low abstraction level.  If we need higher alignment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
  // we can either pass an alignment to this method or verify alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
  // in one of the methods further up the call chain.  See bug 5044738.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
  assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
  // Repeatedly allocate blocks until the block is allocated at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
  // right spot. Give up after max_tries. Note that reserve_memory() will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
  // automatically update _highest_vm_reserved_address if the call is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
  // successful. The variable tracks the highest memory address every reserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
  // by JVM. It is used to detect heap-stack collision if running with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
  // fixed-stack LinuxThreads. Because here we may attempt to reserve more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
  // space than needed, it could confuse the collision detecting code. To
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
  // solve the problem, save current _highest_vm_reserved_address and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
  // calculate the correct value before return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
  address old_highest = _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
  // Linux mmap allows caller to pass an address as hint; give it a try first,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
  // if kernel honors the hint then we can return immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
  char * addr = anon_mmap(requested_addr, bytes, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
  if (addr == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
     return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
     // mmap() is successful but it fails to reserve at the requested address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
     anon_munmap(addr, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
  for (i = 0; i < max_tries; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
    base[i] = reserve_memory(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
    if (base[i] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
      // Is this the block we wanted?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
      if (base[i] == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
        size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
      // Does this overlap the block we wanted? Give back the overlapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
      // parts and try again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
      size_t top_overlap = requested_addr + (bytes + gap) - base[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
      if (top_overlap >= 0 && top_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
        unmap_memory(base[i], top_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
        base[i] += top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
        size[i] = bytes - top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
        size_t bottom_overlap = base[i] + bytes - requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
        if (bottom_overlap >= 0 && bottom_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
          unmap_memory(requested_addr, bottom_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
          size[i] = bytes - bottom_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
          size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
  // Give back the unused reserved pieces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
  for (int j = 0; j < i; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
    if (base[j] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
      unmap_memory(base[j], size[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
  if (i < max_tries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
    _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
    return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
    _highest_vm_reserved_address = old_highest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
size_t os::read(int fd, void *buf, unsigned int nBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
  return ::read(fd, buf, nBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
// TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
// Solaris uses poll(), linux uses park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
// Poll() is likely a better choice, assuming that Thread.interrupt()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
// SIGSEGV, see 4355769.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
  assert(thread == Thread::current(),  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
  ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
  slp->reset() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
  OrderAccess::fence() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
  if (interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
      if (os::is_interrupted(thread, true)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
        return OS_INTRPT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3822
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
      if(millis <= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
        return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
        assert(thread->is_Java_thread(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
        JavaThread *jt = (JavaThread *) thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
        ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
        OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
        jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
        // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
        // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
        slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
        // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
        jt->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
      // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
      // the 1st iteration ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3860
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3861
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
      if(millis <= 0) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3867
      slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3868
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3869
    return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3871
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3872
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3873
int os::naked_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3874
  // %% make the sleep time an integer flag. for now use 1 millisec.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3875
  return os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3876
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3877
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3878
// Sleep forever; naked call to OS-specific sleep; use with CAUTION
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3879
void os::infinite_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3880
  while (true) {    // sleep forever ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3881
    ::sleep(100);   // ... 100 seconds at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3882
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3883
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3884
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3885
// Used to convert frequent JVM_Yield() to nops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3886
bool os::dont_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3887
  return DontYieldALot;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3888
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3890
void os::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3891
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3892
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3893
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3894
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3896
void os::yield_all(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3897
  // Yields to all threads, including threads with lower priorities
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
  // Threads on Linux are all with same priority. The Solaris style
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3899
  // os::yield_all() with nanosleep(1ms) is not necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3900
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3901
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3902
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
// Called from the tight loops to possibly influence time-sharing heuristics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
void os::loop_breaker(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3905
  os::yield_all(attempts);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3907
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3908
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3909
// thread priority support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3910
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3911
// Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3912
// only supports dynamic priority, static priority must be zero. For real-time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3913
// applications, Linux supports SCHED_RR which allows static priority (1-99).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3914
// However, for large multi-threaded applications, SCHED_RR is not only slower
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3915
// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3916
// of 5 runs - Sep 2005).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3917
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3918
// The following code actually changes the niceness of kernel-thread/LWP. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3919
// has an assumption that setpriority() only modifies one kernel-thread/LWP,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3920
// not the entire user process, and user level threads are 1:1 mapped to kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3921
// threads. It has always been the case, but could change in the future. For
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3922
// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3923
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3925
int os::java_to_os_priority[CriticalPriority + 1] = {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3926
  19,              // 0 Entry should never be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3927
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
   4,              // 1 MinPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
   3,              // 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
   2,              // 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
   1,              // 4
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
   0,              // 5 NormPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
  -1,              // 6
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
  -2,              // 7
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
  -3,              // 8
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
  -4,              // 9 NearMaxPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3940
  -5,              // 10 MaxPriority
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3941
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3942
  -5               // 11 CriticalPriority
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
static int prio_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
  if (ThreadPriorityPolicy == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
    // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
    // if effective uid is not root. Perhaps, a more elegant way of doing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
    // this is to test CAP_SYS_NICE capability, but that will require libcap.so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
    if (geteuid() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
      if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
        warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
      ThreadPriorityPolicy = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
  }
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3957
  if (UseCriticalJavaThreadPriority) {
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3958
    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
  3959
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
OSReturn os::set_native_priority(Thread* thread, int newpri) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
  int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
  return (ret == 0) ? OS_OK : OS_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
    *priority_ptr = java_to_os_priority[NormPriority];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
    return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3974
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3975
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
  errno = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
  *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
  return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
// Hint to the underlying OS that a task switch would not be good.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
// Void return because it's a hint and can fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
void os::hint_no_preempt() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
// suspend/resume support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
//  the low-level signal-based suspend/resume support is a remnant from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
//  old VM-suspension that used to be for java-suspension, safepoints etc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
//  within hotspot. Now there is a single use-case for this:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
//    - calling get_thread_pc() on the VMThread by the flat-profiler task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
//      that runs in the watcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
//  The remaining code is greatly simplified from the more general suspension
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
//  code that used to be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3996
//  The protocol is quite simple:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3997
//  - suspend:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3998
//      - sends a signal to the target thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
//      - polls the suspend state of the osthread using a yield loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4000
//      - target thread signal handler (SR_handler) sets suspend state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4001
//        and blocks in sigsuspend until continued
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4002
//  - resume:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4003
//      - sets target osthread state to continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
//      - sends signal to end the sigsuspend loop in the SR_handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4006
//  Note that the SR_lock plays no role in this suspend/resume protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4007
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
static void resume_clear_context(OSThread *osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4010
  osthread->set_ucontext(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
  osthread->set_siginfo(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4012
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4013
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4014
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4015
  osthread->set_ucontext(context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
  osthread->set_siginfo(siginfo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4019
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4020
// Handler function invoked when a thread's execution is suspended or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4021
// resumed. We have to be careful that only async-safe functions are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4022
// called here (Note: most pthread functions are not async safe and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4023
// should be avoided.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
// Note: sigwait() is a more natural fit than sigsuspend() from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
// interface point of view, but sigwait() prevents the signal hander
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
// from being run. libpthread would get very confused by not having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
// its signal handlers run and prevents sigwait()'s use with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
// mutex granting granting signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
//
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4031
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
  // Save and restore errno to avoid confusing native code with EINTR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
  // after sigsuspend.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
  int old_errno = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
  OSThread* osthread = thread->osthread();
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4040
  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
  4041
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4042
  os::SuspendResume::State current = osthread->sr.state();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4043
  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
    suspend_save_context(osthread, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4046
    // 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
  4047
    os::SuspendResume::State state = osthread->sr.suspended();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4048
    if (state == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4049
      sigset_t suspend_set;  // signals for sigsuspend()
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4050
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4051
      // get current set of blocked signals and unblock resume signal
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4052
      pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4053
      sigdelset(&suspend_set, SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4054
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4055
      sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4056
      // wait here until we are resumed
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4057
      while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4058
        sigsuspend(&suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4059
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4060
        os::SuspendResume::State result = osthread->sr.running();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4061
        if (result == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4062
          sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4063
          break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4064
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4065
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4066
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4067
    } else if (state == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4068
      // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4069
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4070
      ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4071
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
    resume_clear_context(osthread);
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4074
  } else if (current == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4075
    // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4076
  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4077
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
  } else {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4079
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
  errno = old_errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4083
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
static int SR_initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
  /* Get signal number to use for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
  if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
    int sig = ::strtol(s, 0, 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
    if (sig > 0 || sig < _NSIG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
        SR_signum = sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
  assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
        "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
  sigemptyset(&SR_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4101
  sigaddset(&SR_sigset, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
  /* Set up signal handler for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
  act.sa_flags = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
  act.sa_handler = (void (*)(int)) SR_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
  // SR_signum is blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
  // 4528190 - We also need to block pthread restart signal (32 on all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
  // supported Linux platforms). Note that LinuxThreads need to block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
  // this signal for all threads to work properly. So we don't have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
  // to use hard-coded signal number when setting up the mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
  pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
  if (sigaction(SR_signum, &act, 0) == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
  // Save signal flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
  os::Linux::set_our_sigflags(SR_signum, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4120
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4123
static int sr_notify(OSThread* osthread) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4124
  int status = pthread_kill(osthread->pthread_id(), SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4125
  assert_status(status == 0, status, "pthread_kill");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4126
  return status;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4127
}
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
// "Randomly" selected value for how long we want to spin
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4130
// before bailing out on suspending a thread, also how often
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4131
// we send a signal to a thread we want to resume
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4132
static const int RANDOMLY_LARGE_INTEGER = 1000000;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4133
static const int RANDOMLY_LARGE_INTEGER2 = 100;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
// returns true on success and false on error - really an error is fatal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
// but this seems the normal response to library errors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4137
static bool do_suspend(OSThread* osthread) {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4138
  assert(osthread->sr.is_running(), "thread should be running");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4139
  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4140
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
  // mark as suspended and send signal
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4142
  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4143
    // failed to switch, state wasn't running?
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4144
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4145
    return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4146
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4147
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4148
  if (sr_notify(osthread) != 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4149
    ShouldNotReachHere();
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
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4152
  // 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
  4153
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4154
    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4155
      break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4156
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4157
      // timeout
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4158
      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4159
      if (cancelled == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4160
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4161
      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4162
        // 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
  4163
        sr_semaphore.wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4164
        break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4165
      } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4166
        ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4167
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4168
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
    }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4170
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4171
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4172
  guarantee(osthread->sr.is_suspended(), "Must be suspended");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4173
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
static void do_resume(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
  assert(osthread->sr.is_suspended(), "thread should be suspended");
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4178
  assert(!sr_semaphore.trywait(), "invalid semaphore state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4179
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4180
  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4181
    // failed to switch to WAKEUP_REQUEST
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4182
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4183
    return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4184
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4185
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4186
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4187
    if (sr_notify(osthread) == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4188
      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4189
        if (osthread->sr.is_running()) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4190
          return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4191
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4192
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4193
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4194
      ShouldNotReachHere();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
  }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4197
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4198
  guarantee(osthread->sr.is_running(), "Must be running!");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
// interrupt support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
void os::interrupt(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4209
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4210
  if (!osthread->interrupted()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
    osthread->set_interrupted(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
    // More than one thread can get here with the same value of osthread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4213
    // resulting in multiple notifications.  We do, however, want the store
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4214
    // to interrupted() to be visible to other threads before we execute unpark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4215
    OrderAccess::fence();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
    ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
    if (slp != NULL) slp->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4220
  // For JSR166. Unpark even if interrupt status already was set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4221
  if (thread->is_Java_thread())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
    ((JavaThread*)thread)->parker()->unpark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
  ParkEvent * ev = thread->_ParkEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
  if (ev != NULL) ev->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
  bool interrupted = osthread->interrupted();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
  if (interrupted && clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
    osthread->set_interrupted(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4239
    // consider thread->_SleepEvent->reset() ... optional optimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4240
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
  return interrupted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
///////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
// signal handling (except suspend/resume)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
// This routine may be used by user applications as a "hook" to catch signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
// The user-defined signal handler must pass unrecognized signals to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
// routine, and if it returns true (non-zero), then the signal handler must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
// return immediately.  If the flag "abort_if_unrecognized" is true, then this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
// routine will never retun false (zero), but instead will execute a VM panic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
// routine kill the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4254
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
// If this routine returns false, it is OK to call it again.  This allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
// the user-defined signal handler to perform checks either before or after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
// the VM performs its own checks.  Naturally, the user code would be making
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
// a serious error if it tried to handle an exception (such as a null check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
// or breakpoint) that the VM was generating for its own correct operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
// This routine may recognize any of the following kinds of signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
//    SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
// It should be consulted by handlers for any of those signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
// The caller of this routine must pass in the three arguments supplied
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
// to the function referred to in the "sa_sigaction" (not the "sa_handler")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
// field of the structure passed to sigaction().  This routine assumes that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
// Note that the VM will print warnings if it detects conflicting signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
//
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  4273
extern "C" JNIEXPORT int
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
                        void* ucontext, int abort_if_unrecognized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
void signalHandler(int sig, siginfo_t* info, void* uc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
  assert(info != NULL && uc != NULL, "it must be old kernel");
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4279
  int orig_errno = errno;  // Preserve errno value over signal handler.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
  JVM_handle_linux_signal(sig, info, uc, true);
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4281
  errno = orig_errno;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
// This boolean allows users to forward their own non-matching signals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
// to JVM_handle_linux_signal, harmlessly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
bool os::Linux::signal_handlers_are_installed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
// For signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
struct sigaction os::Linux::sigact[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
unsigned int os::Linux::sigs = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
bool os::Linux::libjsig_is_loaded = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
typedef struct sigaction *(*get_signal_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
get_signal_t os::Linux::get_signal_action = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
struct sigaction* os::Linux::get_chained_signal_action(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
  struct sigaction *actp = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
  if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    // Retrieve the old signal handler from libjsig
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
    actp = (*get_signal_action)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
  if (actp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
    // Retrieve the preinstalled signal handler from jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
    actp = get_preinstalled_handler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
  return actp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
static bool call_chained_handler(struct sigaction *actp, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
                                 siginfo_t *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
  // Call the old signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
  if (actp->sa_handler == SIG_DFL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
    // It's more reasonable to let jvm treat it as an unexpected exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
    // instead of taking the default action.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
  } else if (actp->sa_handler != SIG_IGN) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
    if ((actp->sa_flags & SA_NODEFER) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
      // automaticlly block the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
      sigaddset(&(actp->sa_mask), sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
    sa_handler_t hand;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
    sa_sigaction_t sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
    bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
    // retrieve the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
      sa = actp->sa_sigaction;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
      hand = actp->sa_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
    if ((actp->sa_flags & SA_RESETHAND) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
      actp->sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
    // try to honor the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
    sigset_t oset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
    pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
    // call into the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
      (*sa)(sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
      (*hand)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
    // restore the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
    pthread_sigmask(SIG_SETMASK, &oset, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
  // Tell jvm's signal handler the signal is taken care of.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
  bool chained = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
  // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
  if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
    struct sigaction *actp = get_chained_signal_action(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
    if (actp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
      chained = call_chained_handler(actp, sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
  return chained;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
  if ((( (unsigned int)1 << sig ) & sigs) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
    return &sigact[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
  sigact[sig] = oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
  sigs |= (unsigned int)1 << sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
// for diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
int os::Linux::sigflags[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
int os::Linux::get_our_sigflags(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  return sigflags[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
void os::Linux::set_our_sigflags(int sig, int flags) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
  sigflags[sig] = flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
void os::Linux::set_signal_handler(int sig, bool set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
  // Check for overwrite.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
  struct sigaction oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
  sigaction(sig, (struct sigaction*)NULL, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
  void* oldhand = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
                ? CAST_FROM_FN_PTR(void*,  oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
                : CAST_FROM_FN_PTR(void*,  oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
  if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
      oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
      oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
    if (AllowUserSignalHandlers || !set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
      // Do not overwrite; user takes responsibility to forward to us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
    } else if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
      // save the old handler in jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
      save_preinstalled_handler(sig, oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
      // libjsig also interposes the sigaction() call below and saves the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
      // old sigaction on it own.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
    } else {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4414
      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4415
                    "%#lx for signal %d.", (long)oldhand, sig));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4419
  struct sigaction sigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
  sigAct.sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
  if (!set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
    sigAct.sa_sigaction = signalHandler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
  // Save flags, which are set by ours
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
  sigflags[sig] = sigAct.sa_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
  int ret = sigaction(sig, &sigAct, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
  assert(ret == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
  void* oldhand2  = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
                  ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
                  : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
  assert(oldhand2 == oldhand, "no concurrent signal handler installation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
// install signal handlers for signals that HotSpot needs to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
// handle in order to support Java-level exception handling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
void os::Linux::install_signal_handlers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
  if (!signal_handlers_are_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
    signal_handlers_are_installed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
    // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4449
    typedef void (*signal_setting_t)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4450
    signal_setting_t begin_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
    signal_setting_t end_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
    begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
                             dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
    if (begin_signal_setting != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
      end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
                             dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
      get_signal_action = CAST_TO_FN_PTR(get_signal_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
                            dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
      libjsig_is_loaded = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
      assert(UseSignalChaining, "should enable signal-chaining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
      // Tell libjsig jvm is setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
      (*begin_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
    set_signal_handler(SIGSEGV, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
    set_signal_handler(SIGPIPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
    set_signal_handler(SIGBUS, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
    set_signal_handler(SIGILL, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4471
    set_signal_handler(SIGFPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4472
    set_signal_handler(SIGXFSZ, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
      // Tell libjsig jvm finishes setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
      (*end_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
    // 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
  4480
    // 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
  4481
    // Log that signal checking is off only if -verbose:jni is specified.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
    if (CheckJNICalls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4483
      if (libjsig_is_loaded) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4484
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4485
          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
  4486
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4487
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4488
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4489
      if (AllowUserSignalHandlers) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4490
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4491
          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
  4492
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
// This is the fastest way to get thread cpu time on Linux.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
// Returns cpu time (user+sys) for any thread, not only for current.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
// POSIX compliant clocks are implemented in the kernels 2.6.16+.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
// It might work on 2.6.10+ with a special kernel/glibc patch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
// For reference, please, see IEEE Std 1003.1-2004:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
//   http://www.unix.org/single_unix_specification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4508
  int rc = os::Linux::clock_gettime(clockid, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
  assert(rc == 0, "clock_gettime is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  4511
  return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
/////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
// glibc on Linux platform uses non-documented flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
// to indicate, that some special sort of signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
// trampoline is used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
// We will never set this flag, and we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
// ignore this flag in our diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4520
#ifdef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
#undef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
#define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
static const char* get_signal_handler_name(address handler,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
                                           char* buf, int buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
  int offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
  bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4529
  if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
    // skip directory names
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
    const char *p1, *p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
    p1 = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
    size_t len = strlen(os::file_separator());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
    while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
    jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
    jio_snprintf(buf, buflen, PTR_FORMAT, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4540
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4541
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4542
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4543
                                 char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4544
  struct sigaction sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4546
  sigaction(sig, NULL, &sa);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4547
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4548
  // See comment for SIGNIFICANT_SIGNAL_MASK define
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
  sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4551
  st->print("%s: ", os::exception_name(sig, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
  address handler = (sa.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4554
    ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
    : CAST_FROM_FN_PTR(address, sa.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
  if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
    st->print("SIG_DFL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
  } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
    st->print("SIG_IGN");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
    st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
  st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
  address rh = VMError::get_resetted_sighandler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
  // May be, handler was resetted by VMError?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
  if(rh != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
    handler = rh;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
    sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4572
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4574
  st->print(", sa_flags="   PTR32_FORMAT, sa.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4576
  // Check: is it our handler?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4577
  if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4578
     handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4579
    // It is our signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4580
    // check for flags, reset system-used one!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4581
    if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4582
      st->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4583
                ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4584
                os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4585
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4586
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4587
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4588
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4591
#define DO_SIGNAL_CHECK(sig) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4592
  if (!sigismember(&check_signal_done, sig)) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4593
    os::Linux::check_signal_handler(sig)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4594
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4595
// This method is a periodic task to check for misbehaving JNI applications
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4596
// under CheckJNI, we can add any periodic checks here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4597
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4598
void os::run_periodic_checks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4599
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4600
  if (check_signals == false) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4602
  // SEGV and BUS if overridden could potentially prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
  // generation of hs*.log in the event of a crash, debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
  // such a case can be very challenging, so we absolutely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
  // check the following for a good measure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
  DO_SIGNAL_CHECK(SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
  DO_SIGNAL_CHECK(SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
  DO_SIGNAL_CHECK(SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
  DO_SIGNAL_CHECK(SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
  DO_SIGNAL_CHECK(SIGPIPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
  DO_SIGNAL_CHECK(SIGXFSZ);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
  // ReduceSignalUsage allows the user to override these handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
  // see comments at the very top and jvm_solaris.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
    DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
    DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
    DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
    DO_SIGNAL_CHECK(BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
  DO_SIGNAL_CHECK(SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
static os_sigaction_t os_sigaction = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
void os::Linux::check_signal_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
  char buf[O_BUFLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
  address jvmHandler = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
  if (os_sigaction == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
    // only trust the default sigaction, in case it has been interposed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
    os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
    if (os_sigaction == NULL) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
  os_sigaction(sig, (struct sigaction*)NULL, &act);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
  act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
  address thisHandler = (act.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4649
    ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4650
    : CAST_FROM_FN_PTR(address, act.sa_handler) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4652
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4653
  switch(sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4654
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4655
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4656
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4657
  case SIGPIPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4658
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4659
  case SIGXFSZ:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4660
    jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4661
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4663
  case SHUTDOWN1_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
  case SHUTDOWN2_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
  case SHUTDOWN3_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
  case BREAK_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
    jvmHandler = (address)user_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
  case INTERRUPT_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4671
    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4674
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4675
    if (sig == SR_signum) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4676
      jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4677
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4683
  if (thisHandler != jvmHandler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4684
    tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4685
    tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4686
    tty->print_cr("  found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
  } 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
  4690
    tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
    tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
    tty->print_cr("  found:" PTR32_FORMAT, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
  // Dump all the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
  if (sigismember(&check_signal_done, sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4699
    print_signal_handlers(tty, buf, O_BUFLEN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4700
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4701
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4703
extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4705
extern bool signal_name(int signo, char* buf, size_t len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4707
const char* os::exception_name(int exception_code, char* buf, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4708
  if (0 < exception_code && exception_code <= SIGRTMAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4709
    // signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4710
    if (!signal_name(exception_code, buf, size)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4711
      jio_snprintf(buf, size, "SIG%d", exception_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4712
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4713
    return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4714
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4715
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4716
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4717
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4718
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4719
// this is called _before_ the most of global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4720
void os::init(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4721
  char dummy;   /* used to get a guess on initial stack address */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4722
//  first_hrtime = gethrtime();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4723
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4724
  // With LinuxThreads the JavaMain thread pid (primordial thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4725
  // is different than the pid of the java launcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4726
  // So, on Linux, the launcher thread pid is passed to the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4727
  // via the sun.java.launcher.pid property.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4728
  // Use this property instead of getpid() if it was correctly passed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4729
  // See bug 6351349.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4730
  pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4732
  _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
  clock_tics_per_sec = sysconf(_SC_CLK_TCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
  init_random(1234567);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
  ThreadCritical::initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4740
  Linux::set_page_size(sysconf(_SC_PAGESIZE));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4741
  if (Linux::page_size() == -1) {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4742
    fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4743
                  strerror(errno)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
  init_page_sizes((size_t) Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4746
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
  Linux::initialize_system_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
  // main_thread points to the aboriginal thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
  Linux::_main_thread = pthread_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
  Linux::clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
  initial_time_count = os::elapsed_counter();
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4754
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4755
  // pthread_condattr initialization for monotonic clock
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4756
  int status;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4757
  pthread_condattr_t* _condattr = os::Linux::condAttr();
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4758
  if ((status = pthread_condattr_init(_condattr)) != 0) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4759
    fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4760
  }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4761
  // Only set the clock if CLOCK_MONOTONIC is available
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4762
  if (Linux::supports_monotonic_clock()) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4763
    if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4764
      if (status == EINVAL) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4765
        warning("Unable to use monotonic clock with relative timed-waits" \
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4766
                " - changes to the time-of-day clock may have adverse affects");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4767
      } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4768
        fatal(err_msg("pthread_condattr_setclock: %s", strerror(status)));
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4769
      }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4770
    }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4771
  }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4772
  // else it defaults to CLOCK_REALTIME
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  4773
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  4774
  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
  4775
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4776
  // 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
  4777
  // 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
  4778
  // 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
  4779
  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
  4780
    StackYellowPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4781
    StackRedPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4782
    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
  4783
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4786
// To install functions for atexit system call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4787
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
  static void perfMemory_exit_helper() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
    perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4792
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
// this is called _after_ the global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
jint os::init_2(void)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4795
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
  Linux::fast_thread_clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
  // Allocate a single page and mark it as readable for safepoint polling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
  address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
  guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
  os::set_polling_page( polling_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
  if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4809
  if (!UseMembar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4810
    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
  4811
    guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4812
    os::set_memory_serialize_page( mem_serialize_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
    if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
  // initialize suspend/resume support - must do this before signal_sets_init()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
  if (SR_initialize() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
    perror("SR_initialize failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
    return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4824
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
  Linux::signal_sets_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
  Linux::install_signal_handlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4828
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4829
  // 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
  4830
  // the java system classes, including StackOverflowError - depends on page
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4831
  // 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
  4832
  // 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
  4833
  // class initialization depending on 32 or 64 bit VM.
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4834
  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
  4835
            (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
  4836
                    (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
  4837
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
  size_t threadStackSizeInBytes = ThreadStackSize * K;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
  if (threadStackSizeInBytes != 0 &&
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4840
      threadStackSizeInBytes < os::Linux::min_stack_allowed) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
        tty->print_cr("\nThe stack size specified is too small, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4842
                      "Specify at least %dk",
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4843
                      os::Linux::min_stack_allowed/ K);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
        return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
  // Make the stack size a multiple of the page size so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
  // the yellow/red zones can be guarded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
        vm_page_size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
  Linux::capture_initial_stack(JavaThread::stack_size_at_create());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
  Linux::libpthread_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
  if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4856
     tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
          Linux::glibc_version(), Linux::libpthread_version(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
          Linux::is_floating_stack() ? "floating stack" : "fixed stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4861
  if (UseNUMA) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4862
    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
  4863
      UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4864
    } else {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4865
      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
  4866
        // 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
  4867
        UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4868
      }
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4869
    }
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4870
    // 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
  4871
    // 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
  4872
    // 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
  4873
    // disable adaptive resizing.
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4874
    if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4875
      if (FLAG_IS_DEFAULT(UseNUMA)) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4876
        UseNUMA = false;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4877
      } else {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4878
        if (FLAG_IS_DEFAULT(UseLargePages) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4879
            FLAG_IS_DEFAULT(UseSHM) &&
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4880
            FLAG_IS_DEFAULT(UseHugeTLBFS)) {
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4881
          UseLargePages = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4882
        } else {
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  4883
          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
  4884
          UseAdaptiveSizePolicy = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4885
          UseAdaptiveNUMAChunkSizing = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4886
        }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4887
      }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4888
    }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4889
    if (!UseNUMA && ForceNUMA) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4890
      UseNUMA = true;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4891
    }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4892
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4893
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4894
  if (MaxFDLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4895
    // set the number of file descriptors to max. print out error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4896
    // if getrlimit/setrlimit fails but continue regardless.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4897
    struct rlimit nbr_files;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4898
    int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4899
    if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4900
      if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4901
        perror("os::init_2 getrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4902
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4903
      nbr_files.rlim_cur = nbr_files.rlim_max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4904
      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4905
      if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4906
        if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4907
          perror("os::init_2 setrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4908
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4909
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4910
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4912
  // Initialize lock used to serialize thread creation (see os::create_thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4913
  Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4915
  // at-exit methods are called in the reverse order of their registration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4916
  // atexit functions are called on return from main or as a result of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4917
  // call to exit(3C). There can be only 32 of these functions registered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4918
  // and atexit() does not set errno.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4919
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4920
  if (PerfAllowAtExitRegistration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4921
    // only register atexit functions if PerfAllowAtExitRegistration is set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4922
    // atexit functions can be delayed until process exit time, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4923
    // can be problematic for embedded VM situations. Embedded VMs should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4924
    // call DestroyJavaVM() to assure that VM resources are released.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4926
    // note: perfMemory_exit_helper atexit function may be removed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4927
    // the future if the appropriate cleanup code can be added to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4928
    // VM_Exit VMOperation's doit method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4929
    if (atexit(perfMemory_exit_helper) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4930
      warning("os::init2 atexit(perfMemory_exit_helper) failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4931
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4932
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4933
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4934
  // initialize thread priority policy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4935
  prio_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4937
  return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4938
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4939
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4940
// 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
  4941
void os::init_3(void)
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4942
{
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4943
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4944
  // Start the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4945
  if (LowMemoryProtection) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4946
    MemNotifyThread::start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4947
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4948
  return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4949
#endif
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4950
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4951
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4952
// Mark the polling page as unreadable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
void os::make_polling_page_unreadable(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
  if( !guard_memory((char*)_polling_page, Linux::page_size()) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4955
    fatal("Could not disable polling page");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
// Mark the polling page as readable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4959
void os::make_polling_page_readable(void) {
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4960
  if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4961
    fatal("Could not enable polling page");
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4962
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
int os::active_processor_count() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
  // Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
  // so just return the number of online processors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
  return online_cpus;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4972
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4973
void os::set_native_thread_name(const char *name) {
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4974
  // Not yet implemented.
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4975
  return;
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4976
}
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4977
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4978
bool os::distribute_processes(uint length, uint* distribution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4979
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4980
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4981
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4983
bool os::bind_to_processor(uint processor_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4984
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4985
  return false;
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
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4990
void os::SuspendedThreadTask::internal_do_task() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4991
  if (do_suspend(_thread->osthread())) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4992
    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4993
    do_task(context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4994
    do_resume(_thread->osthread());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4995
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4996
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4997
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4998
class PcFetcher : public os::SuspendedThreadTask {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4999
public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5000
  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5001
  ExtendedPC result();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5002
protected:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5003
  void do_task(const os::SuspendedThreadTaskContext& context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5004
private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5005
  ExtendedPC _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5006
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5007
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5008
ExtendedPC PcFetcher::result() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5009
  guarantee(is_done(), "task is not done yet.");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5010
  return _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5011
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5012
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5013
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5014
  Thread* thread = context.thread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5015
  OSThread* osthread = thread->osthread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5016
  if (osthread->ucontext() != NULL) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5017
    _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5018
  } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5019
    // NULL context is unexpected, double-check this is the VMThread
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5020
    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5021
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5022
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5023
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
// Suspends the target using the signal mechanism and then grabs the PC before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
// resuming the target. Used by the flat-profiler only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
ExtendedPC os::get_thread_pc(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
  // Make sure that it is called by the watcher for the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
  assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
  assert(thread->is_VM_thread(), "Can only be called for VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5031
  PcFetcher fetcher(thread);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5032
  fetcher.run();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5033
  return fetcher.result();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
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
  5037
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
   if (is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
      return pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
   } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
      // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
      // word back to default 64bit precision if condvar is signaled. Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
      // wants 53bit precision.  Save and restore current value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
      int fpu = get_fpu_control_word();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
      int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5046
      set_fpu_control_word(fpu);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
      return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
// debug support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5054
bool os::find(address addr, outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5056
  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
  5057
  if (dladdr(addr, &dlinfo) != 0) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5058
    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
  5059
    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5060
      st->print("%s+%#x", dlinfo.dli_sname,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
                 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
  5062
    } else if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5063
      st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
    } else {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5065
      st->print("<absolute address>");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5067
    if (dlinfo.dli_fname != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5068
      st->print(" in %s", dlinfo.dli_fname);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5070
    if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5071
      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
    }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5073
    st->cr();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5075
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
      // decode some bytes around the PC
16670
4af09aff4237 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 16669
diff changeset
  5077
      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
  5078
      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
      address       lowest = (address) dlinfo.dli_sname;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
      if (!lowest)  lowest = (address) dlinfo.dli_fbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
      if (begin < lowest)  begin = lowest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5082
      Dl_info dlinfo2;
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  5083
      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
          && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
        end = (address) dlinfo2.dli_saddr;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5086
      Disassembler::decode(begin, end, st);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
// misc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
// This does not do anything on Linux. This is basically a hook for being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
// able to use structured exception handling (thread-local exception filters)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
// on, e.g., Win32.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
                         JavaCallArguments* args, Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
  f(value, method, args, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5103
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
void os::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
int os::message_box(const char* title, const char* message) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5109
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
  fdStream err(defaultStream::error_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5112
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5113
  err.print_raw_cr(title);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5114
  for (i = 0; i < 78; i++) err.print_raw("-");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5115
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5116
  err.print_raw_cr(message);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5117
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5118
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
  char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
  // Prevent process from exiting upon "read error" without consuming all CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
  while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
  return buf[0] == 'y' || buf[0] == 'Y';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5127
int os::stat(const char *path, struct stat *sbuf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
  char pathbuf[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
  if (strlen(path) > MAX_PATH - 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
    errno = ENAMETOOLONG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
  }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5133
  os::native_path(strcpy(pathbuf, path));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
  return ::stat(pathbuf, sbuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5137
bool os::check_heap(bool force) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
  return ::vsnprintf(buf, count, format, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
// Is a (classpath) directory empty?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
bool os::dir_is_empty(const char* path) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
  DIR *dir = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
  struct dirent *ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
  dir = opendir(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
  if (dir == NULL) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
  /* Scan the directory */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5154
  bool result = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
  char buf[sizeof(struct dirent) + MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
  while (result && (ptr = ::readdir(dir)) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5157
    if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5158
      result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5159
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5160
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5161
  closedir(dir);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5162
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5165
// 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
  5166
// from src/solaris/hpi/src/system_md.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5167
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5168
#ifndef O_DELETE
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5169
#define O_DELETE 0x10000
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5170
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5171
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5172
// 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
  5173
// 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
  5174
// 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
  5175
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5176
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
  5177
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5178
  if (strlen(path) > MAX_PATH - 1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5179
    errno = ENAMETOOLONG;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5180
    return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5181
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5182
  int fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5183
  int o_delete = (oflag & O_DELETE);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5184
  oflag = oflag & ~O_DELETE;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5185
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5186
  fd = ::open64(path, oflag, mode);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5187
  if (fd == -1) return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5188
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5189
  //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
  5190
  {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5191
    struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5192
    int ret = ::fstat64(fd, &buf64);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5193
    int st_mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5194
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5195
    if (ret != -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5196
      if ((st_mode & S_IFMT) == S_IFDIR) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5197
        errno = EISDIR;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5198
        ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5199
        return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5200
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5201
    } else {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5202
      ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5203
      return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5204
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5205
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5206
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5207
    /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5208
     * 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
  5209
     * specifically destined for a subprocess should have the
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5210
     * 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
  5211
     * 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
  5212
     * 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
  5213
     * UNIXProcess.c), and this in turn might:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5214
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5215
     * - 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
  5216
     *   descriptors, resulting in mysterious hangs, or
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5217
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5218
     * - 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
  5219
     *   suffering from bug 1085341.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5220
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5221
     * (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
  5222
     * design flaw)
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
     * See:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5225
     * 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
  5226
     * 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
  5227
     * 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
  5228
     */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5229
#ifdef FD_CLOEXEC
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
        int flags = ::fcntl(fd, F_GETFD);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5232
        if (flags != -1)
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5233
            ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5234
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5235
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5236
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5237
  if (o_delete != 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5238
    ::unlink(path);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5239
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5240
  return fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5241
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5242
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5243
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
// create binary file, rewriting existing file if required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
int os::create_binary_file(const char* path, bool rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
  int oflags = O_WRONLY | O_CREAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
  if (!rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
    oflags |= O_EXCL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
  return ::open64(path, oflags, S_IREAD | S_IWRITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
// return current position of file pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
jlong os::current_file_offset(int fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
  return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
// move file pointer to the specified offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
jlong os::seek_to_file_offset(int fd, jlong offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
  return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5263
// This code originates from JDK's sysAvailable
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5264
// 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
  5265
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5266
int os::available(int fd, jlong *bytes) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5267
  jlong cur, end;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5268
  int mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5269
  struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5270
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5271
  if (::fstat64(fd, &buf64) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5272
    mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5273
    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
  5274
      /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5275
      * 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
  5276
      * 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
  5277
      * blocking, interruptible calls in this file.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5278
      */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5279
      int n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5280
      if (::ioctl(fd, FIONREAD, &n) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5281
        *bytes = n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5282
        return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5283
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5284
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5285
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5286
  if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5287
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5288
  } 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
  5289
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5290
  } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5291
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5292
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5293
  *bytes = end - cur;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5294
  return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5295
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5296
7458
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5297
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
  5298
  // 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
  5299
  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
  5300
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5301
  //%% 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
  5302
  // 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
  5303
  return (ret < 0) ? 0 : 1;
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5304
}
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5305
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
// Map a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5307
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
                     char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
                     bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
  int prot;
11967
ce179af268b1 7142641: -Xshared:on fails on ARM
dlong
parents: 11601
diff changeset
  5311
  int flags = MAP_PRIVATE;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
  if (read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
    prot = PROT_READ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
    prot = PROT_READ | PROT_WRITE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
  if (allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
    prot |= PROT_EXEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
  char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
                                     fd, file_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
  if (mapped_address == MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
  return mapped_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
// Remap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5337
char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
                       char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
                       bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
  // same as map_memory() on this OS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
                        allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
// Unmap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5347
bool os::pd_unmap_memory(char* addr, size_t bytes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
  return munmap(addr, bytes) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5349
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5350
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5351
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
static clockid_t thread_cpu_clockid(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
  pthread_t tid = thread->osthread()->pthread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5356
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
  // Get thread clockid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
  int rc = os::Linux::pthread_getcpuclockid(tid, &clockid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
  assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
  return clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
// are used by JVM M&M and JVMTI to get user+sys or user CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5365
// of a thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
// the fast estimate available on the platform.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
jlong os::current_thread_cpu_time() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
    // return user + sys since the cost is the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
    return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
jlong os::thread_cpu_time(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
  // consistent with what current_thread_cpu_time() returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
    return slow_thread_cpu_time(thread, true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
    return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
    return slow_thread_cpu_time(thread, user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
//  -1 on error.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  static bool proc_task_unchecked = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  static const char *proc_stat_path = "/proc/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
  pid_t  tid = thread->osthread()->thread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
  char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5414
  int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5415
  char proc_name[64];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5416
  int count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
  long sys_time, user_time;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5418
  char cdummy;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
  int idummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
  long ldummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5421
  FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5422
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5423
  // The /proc/<tid>/stat aggregates per-process usage on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5424
  // new Linux kernels 2.6+ where NPTL is supported.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5425
  // The /proc/self/task/<tid>/stat still has the per-thread usage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5426
  // 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
  5427
  // 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
  5428
  // /proc/self/task, so we check its availability.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5429
  if (proc_task_unchecked && os::Linux::is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5430
    // This is executed only once
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5431
    proc_task_unchecked = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5432
    fp = fopen("/proc/self/task", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5433
    if (fp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5434
      proc_stat_path = "/proc/self/task/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5435
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5436
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5437
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5438
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5439
  sprintf(proc_name, proc_stat_path, tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5440
  fp = fopen(proc_name, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5441
  if ( fp == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5442
  statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5443
  stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5444
  fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5446
  // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5447
  // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5448
  // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5449
  //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5450
  // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5451
  // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
  s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
  if (s == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
  // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
  do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5458
  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
  5459
                 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
                 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
                 &user_time, &sys_time);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5462
  if ( count != 13 ) return -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
  if (user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
    return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
    return (jlong)user_time * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
bool os::is_thread_cpu_time_supported() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
// System loadavg support.  Returns -1 if load average cannot be obtained.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
// Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
// so just return the system wide load average.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
int os::loadavg(double loadavg[], int nelem) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
  return ::getloadavg(loadavg, nelem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
void os::pause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
  char filename[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
  if (fd != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
    struct stat buf;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5506
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
    while (::stat(filename, &buf) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
      (void)::poll(NULL, 0, 100);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5509
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5510
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5511
    jio_fprintf(stderr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
      "Could not open pause file '%s', continuing immediately.\n", filename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
// Refer to the comments in os_solaris.cpp park-unpark.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
// hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
// For specifics regarding the bug see GLIBC BUGID 261237 :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5522
//    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5523
// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
// is used.  (The simple C test-case provided in the GLIBC bug report manifests the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
// hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
// and monitorenter when we're using 1-0 locking.  All those operations may result in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5528
// calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
// of libpthread avoids the problem, but isn't practical.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
// Possible remedies:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
// 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
//      This is palliative and probabilistic, however.  If the thread is preempted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
//      between the call to compute_abstime() and pthread_cond_timedwait(), more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
//      than the minimum period may have passed, and the abstime may be stale (in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5537
//      past) resultin in a hang.   Using this technique reduces the odds of a hang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5538
//      but the JVM is still vulnerable, particularly on heavily loaded systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5539
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
// 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
//      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5542
//      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5543
//      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5544
//      thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5545
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
// 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
//      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
//      a timeout request to the chron thread and then blocking via pthread_cond_wait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
//      This also works well.  In fact it avoids kernel-level scalability impediments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
//      on certain platforms that don't handle lots of active pthread_cond_timedwait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
//      timers in a graceful fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
// 4.   When the abstime value is in the past it appears that control returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
//      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
//      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
//      can avoid the problem by reinitializing the condvar -- by cond_destroy()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
//      followed by cond_init() -- after all calls to pthread_cond_timedwait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5558
//      It may be possible to avoid reinitialization by checking the return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
//      value from pthread_cond_timedwait().  In addition to reinitializing the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
//      condvar we must establish the invariant that cond_signal() is only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
//      within critical sections protected by the adjunct mutex.  This prevents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
//      cond_signal() from "seeing" a condvar that's in the midst of being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
//      reinitialized or that is corrupt.  Sadly, this invariant obviates the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
//      desirable signal-after-unlock optimization that avoids futile context switching.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
//      I'm also concerned that some versions of NTPL might allocate an auxilliary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
//      structure when a condvar is used or initialized.  cond_destroy()  would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
//      release the helper structure.  Our reinitialize-after-timedwait fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
//      put excessive stress on malloc/free and locks protecting the c-heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
// We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
// It may be possible to refine (4) by checking the kernel and NTPL verisons
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
// and only enabling the work-around for vulnerable environments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
// utility to compute the abstime argument to timedwait:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
// millis is the relative timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
// abstime will be the absolute timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
// TODO: replace compute_abstime() with unpackTime()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
  if (millis < 0)  millis = 0;
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5582
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
  jlong seconds = millis / 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
  millis %= 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5585
  if (seconds > 50000000) { // see man cond_timedwait(3T)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5586
    seconds = 50000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5587
  }
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5588
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5589
  if (os::Linux::supports_monotonic_clock()) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5590
    struct timespec now;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5591
    int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5592
    assert_status(status == 0, status, "clock_gettime");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5593
    abstime->tv_sec = now.tv_sec  + seconds;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5594
    long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5595
    if (nanos >= NANOSECS_PER_SEC) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5596
      abstime->tv_sec += 1;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5597
      nanos -= NANOSECS_PER_SEC;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5598
    }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5599
    abstime->tv_nsec = nanos;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5600
  } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5601
    struct timeval now;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5602
    int status = gettimeofday(&now, NULL);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5603
    assert(status == 0, "gettimeofday");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5604
    abstime->tv_sec = now.tv_sec  + seconds;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5605
    long usec = now.tv_usec + millis * 1000;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5606
    if (usec >= 1000000) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5607
      abstime->tv_sec += 1;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5608
      usec -= 1000000;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5609
    }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5610
    abstime->tv_nsec = usec * 1000;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5611
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
  return abstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
// Conceptually TryPark() should be equivalent to park(0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
int os::PlatformEvent::TryPark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
    const int v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
    guarantee ((v == 0) || (v == 1), "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5623
    if (Atomic::cmpxchg (0, &_Event, v) == v) return v  ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5625
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5626
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5627
void os::PlatformEvent::park() {       // AKA "down()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
  // Invariant: Only the thread associated with the Event/PlatformEvent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
  // may call park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
  // TODO: assert that _Assoc != NULL or _Assoc == Self
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
  if (v == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
     // Do this the hard way by blocking ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
     int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
     assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
     guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
     ++ _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5643
     while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
        status = pthread_cond_wait(_cond, _mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
        // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
        // Treat this the same as if the wait was interrupted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
        if (status == ETIME) { status = EINTR; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
        assert_status(status == 0 || status == EINTR, status, "cond_wait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5650
     -- _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5652
    _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5653
     status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5654
     assert_status(status == 0, status, "mutex_unlock");
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5655
    // 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
  5656
    // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5657
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
  guarantee (_Event >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5661
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5662
int os::PlatformEvent::park(jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5663
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
  if (v != 0) return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5673
  // We do this the hard way, by blocking the thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
  // Consider enforcing a minimum timeout value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
  struct timespec abst;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5676
  compute_abstime(&abst, millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
  int ret = OS_TIMEOUT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5679
  int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5680
  assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5682
  ++_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5683
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5684
  // Object.wait(timo) will return because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5685
  // (a) notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5686
  // (b) timeout
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5687
  // (c) thread.interrupt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5688
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
  // Thread.interrupt and object.notify{All} both call Event::set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
  // That is, we treat thread.interrupt as a special case of notification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
  // The underlying Solaris implementation, cond_timedwait, admits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
  // spurious/premature wakeups, but the JLS/JVM spec prevents the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
  // JVM from making those visible to Java code.  As such, we must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
  // filter out spurious wakeups.  We assume all ETIME returns are valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
  // TODO: properly differentiate simultaneous notify+interrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
  // In that case, we should propagate the notify to another waiter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
  while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
    status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
      pthread_cond_destroy (_cond);
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5703
      pthread_cond_init (_cond, os::Linux::condAttr()) ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
    assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
                  status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
                  status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
    if (!FilterSpuriousWakeups) break ;                 // previous semantics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
    if (status == ETIME || status == ETIMEDOUT) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
    // We consume and ignore EINTR and spurious wakeups.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
  --_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
  if (_Event >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
     ret = OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5716
  _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5717
  status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5718
  assert_status(status == 0, status, "mutex_unlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
  assert (_nParked == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5720
  // 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
  5721
  // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5722
  OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
  return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
void os::PlatformEvent::unpark() {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5727
  // Transitions for _Event:
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5728
  //    0 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5729
  //    1 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5730
  //   -1 :=> either 0 or 1; must signal target thread
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5731
  //          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
  5732
  //          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
  5733
  //          unpark() calls.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5734
  // See also: "Semaphores in Plan 9" by Mullender & Cox
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5735
  //
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5736
  // 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
  5737
  // 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
  5738
  // 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
  5739
  // 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
  5740
  // 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
  5741
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5742
  if (Atomic::xchg(1, &_Event) >= 0) return;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5743
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5744
  // 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
  5745
  int status = pthread_mutex_lock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5746
  assert_status(status == 0, status, "mutex_lock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5747
  int AnyWaiters = _nParked;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5748
  assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5749
  if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5750
    AnyWaiters = 0;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5751
    pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5752
  }
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5753
  status = pthread_mutex_unlock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5754
  assert_status(status == 0, status, "mutex_unlock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5755
  if (AnyWaiters != 0) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5756
    status = pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5757
    assert_status(status == 0, status, "cond_signal");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5760
  // Note that we signal() _after dropping the lock for "immortal" Events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5761
  // This is safe and avoids a common class of  futile wakeups.  In rare
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5762
  // circumstances this can cause a thread to return prematurely from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5763
  // cond_{timed}wait() but the spurious wakeup is benign and the victim will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5764
  // simply re-test the condition and re-park itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5765
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5767
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5768
// JSR166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5769
// -------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5770
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5771
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5772
 * The solaris and linux implementations of park/unpark are fairly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5773
 * conservative for now, but can be improved. They currently use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5774
 * mutex/condvar pair, plus a a count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5775
 * Park decrements count if > 0, else does a condvar wait.  Unpark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5776
 * sets count to 1 and signals condvar.  Only one thread ever waits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5777
 * on the condvar. Contention seen when trying to park implies that someone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5778
 * is unparking you, so don't wait. And spurious returns are fine, so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5779
 * is no need to track notifications.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5780
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5781
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5782
#define MAX_SECS 100000000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5783
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5784
 * This code is common to linux and solaris and will be moved to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5785
 * common place in dolphin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5786
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5787
 * The passed in time value is either a relative time in nanoseconds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5788
 * or an absolute time in milliseconds. Either way it has to be unpacked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5789
 * into suitable seconds and nanoseconds components and stored in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5790
 * given timespec structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5791
 * Given time is a 64-bit value and the time_t used in the timespec is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5792
 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5793
 * overflow if times way in the future are given. Further on Solaris versions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5794
 * prior to 10 there is a restriction (see cond_timedwait) that the specified
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5795
 * number of seconds, in abstime, is less than current_time  + 100,000,000.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5796
 * As it will be 28 years before "now + 100000000" will overflow we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5797
 * ignore overflow and just impose a hard-limit on seconds using the value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5798
 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5799
 * years from "now".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5800
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5802
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5803
  assert (time > 0, "convertTime");
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5804
  time_t max_secs = 0;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5805
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5806
  if (!os::Linux::supports_monotonic_clock() || isAbsolute) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5807
    struct timeval now;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5808
    int status = gettimeofday(&now, NULL);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5809
    assert(status == 0, "gettimeofday");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5810
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5811
    max_secs = now.tv_sec + MAX_SECS;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5812
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5813
    if (isAbsolute) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5814
      jlong secs = time / 1000;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5815
      if (secs > max_secs) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5816
        absTime->tv_sec = max_secs;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5817
      } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5818
        absTime->tv_sec = secs;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5819
      }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5820
      absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5821
    } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5822
      jlong secs = time / NANOSECS_PER_SEC;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5823
      if (secs >= MAX_SECS) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5824
        absTime->tv_sec = max_secs;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5825
        absTime->tv_nsec = 0;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5826
      } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5827
        absTime->tv_sec = now.tv_sec + secs;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5828
        absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5829
        if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5830
          absTime->tv_nsec -= NANOSECS_PER_SEC;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5831
          ++absTime->tv_sec; // note: this must be <= max_secs
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5832
        }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5833
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5834
    }
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5835
  } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5836
    // must be relative using monotonic clock
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5837
    struct timespec now;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5838
    int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5839
    assert_status(status == 0, status, "clock_gettime");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5840
    max_secs = now.tv_sec + MAX_SECS;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5841
    jlong secs = time / NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5842
    if (secs >= MAX_SECS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5843
      absTime->tv_sec = max_secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5844
      absTime->tv_nsec = 0;
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5845
    } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5846
      absTime->tv_sec = now.tv_sec + secs;
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5847
      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5848
      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5849
        absTime->tv_nsec -= NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5850
        ++absTime->tv_sec; // note: this must be <= max_secs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5851
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5852
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5853
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5854
  assert(absTime->tv_sec >= 0, "tv_sec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5855
  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5856
  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5857
  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5858
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5859
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5860
void Parker::park(bool isAbsolute, jlong time) {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5861
  // Ideally we'd do something useful while spinning, such
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5862
  // as calling unpackTime().
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5863
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5864
  // Optional fast-path check:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5865
  // Return immediately if a permit is available.
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5866
  // We depend on Atomic::xchg() having full barrier semantics
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5867
  // 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
  5868
  if (Atomic::xchg(0, &_counter) > 0) return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5870
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5871
  assert(thread->is_Java_thread(), "Must be JavaThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5872
  JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5874
  // Optional optimization -- avoid state transitions if there's an interrupt pending.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5875
  // Check interrupt before trying to wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5876
  if (Thread::is_interrupted(thread, false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5877
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5878
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5879
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5880
  // Next, demultiplex/decode time arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5881
  timespec absTime;
6962
d49132ce025b 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 6420
diff changeset
  5882
  if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5883
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5884
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5885
  if (time > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5886
    unpackTime(&absTime, isAbsolute, time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5887
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5888
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5890
  // Enter safepoint region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5891
  // Beware of deadlocks such as 6317397.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5892
  // The per-thread Parker:: mutex is a classic leaf-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5893
  // In particular a thread must never block on the Threads_lock while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5894
  // holding the Parker:: mutex.  If safepoints are pending both the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5895
  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5896
  ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5897
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5898
  // Don't wait if cannot get lock since interference arises from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5899
  // unblocking.  Also. check interrupt before trying wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5900
  if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5901
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5902
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5903
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5904
  int status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5905
  if (_counter > 0)  { // no wait needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5906
    _counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5907
    status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5908
    assert (status == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5909
    // 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
  5910
    // 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
  5911
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5912
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5913
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5914
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5915
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5916
  // Don't catch signals while blocked; let the running threads have the signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5917
  // (This allows a debugger to break into the running thread.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5918
  sigset_t oldsigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5919
  sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5920
  pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5921
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5923
  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5924
  jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5925
  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5926
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5927
  assert(_cur_index == -1, "invariant");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5928
  if (time == 0) {
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5929
    _cur_index = REL_INDEX; // arbitrary choice when not timed
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5930
    status = pthread_cond_wait (&_cond[_cur_index], _mutex) ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5931
  } else {
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5932
    _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5933
    status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5934
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5935
      pthread_cond_destroy (&_cond[_cur_index]) ;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5936
      pthread_cond_init    (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5937
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5938
  }
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5939
  _cur_index = -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5940
  assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5941
                status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5942
                status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5943
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5944
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5945
  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5946
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5948
  _counter = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5949
  status = pthread_mutex_unlock(_mutex) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5950
  assert_status(status == 0, status, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5951
  // 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
  5952
  // correctly with each other and Java-level accesses.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5953
  OrderAccess::fence();
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5954
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5955
  // If externally suspended while waiting, re-suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5956
  if (jt->handle_special_suspend_equivalent_condition()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5957
    jt->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5958
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5959
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5960
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5961
void Parker::unpark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5962
  int s, status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5963
  status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5964
  assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5965
  s = _counter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5966
  _counter = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5967
  if (s < 1) {
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5968
    // thread might be parked
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5969
    if (_cur_index != -1) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5970
      // thread is definitely parked
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5971
      if (WorkAroundNPTLTimedWaitHang) {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5972
        status = pthread_cond_signal (&_cond[_cur_index]);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5973
        assert (status == 0, "invariant");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5974
        status = pthread_mutex_unlock(_mutex);
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5975
        assert (status == 0, "invariant");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5976
      } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5977
        status = pthread_mutex_unlock(_mutex);
19964
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5978
        assert (status == 0, "invariant");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5979
        status = pthread_cond_signal (&_cond[_cur_index]);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5980
        assert (status == 0, "invariant");
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5981
      }
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5982
    } else {
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5983
      pthread_mutex_unlock(_mutex);
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5984
      assert (status == 0, "invariant") ;
a3a04a9d29ac 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 19732
diff changeset
  5985
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5986
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5987
    pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5988
    assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5989
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5990
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5991
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5992
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5993
extern char** environ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5994
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5995
#ifndef __NR_fork
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5996
#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5997
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5998
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5999
#ifndef __NR_execve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6000
#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6001
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6003
// Run the specified command in a separate process. Return its exit value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6004
// or -1 on failure (e.g. can't fork a new process).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6005
// Unlike system(), this function can be called from signal handler. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6006
// doesn't block SIGINT et al.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6007
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
  6008
  const char * argv[4] = {"sh", "-c", cmd, NULL};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6010
  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6011
  // pthread_atfork handlers and reset pthread library. All we need is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6012
  // separate process to execve. Make a direct syscall to fork process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6013
  // On IA64 there's no fork syscall, we have to use fork() and hope for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6014
  // the best...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6015
  pid_t pid = NOT_IA64(syscall(__NR_fork);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6016
              IA64_ONLY(fork();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6018
  if (pid < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6019
    // fork failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6020
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6022
  } else if (pid == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6023
    // child process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6025
    // execve() in LinuxThreads will call pthread_kill_other_threads_np()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6026
    // first to kill every thread on the thread list. Because this list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6027
    // not reset by fork() (see notes above), execve() will instead kill
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6028
    // every thread in the parent process. We know this is the only thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6029
    // in the new process, so make a system call directly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6030
    // IA64 should use normal execve() from glibc to match the glibc fork()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6031
    // above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6032
    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
  6033
    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6034
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6035
    // execve failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6036
    _exit(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6038
  } else  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6039
    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6040
    // care about the actual exit code, for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6042
    int status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6044
    // Wait for the child process to exit.  This returns immediately if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6045
    // the child has already exited. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6046
    while (waitpid(pid, &status, 0) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6047
        switch (errno) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6048
        case ECHILD: return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6049
        case EINTR: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6050
        default: return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6051
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6052
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6054
    if (WIFEXITED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6055
       // The child exited normally; get its exit code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6056
       return WEXITSTATUS(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6057
    } else if (WIFSIGNALED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6058
       // The child exited because of a signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6059
       // The best value to return is 0x80 + signal number,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6060
       // because that is what all Unix shells do, and because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6061
       // it allows callers to distinguish between process exit and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6062
       // process death by signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6063
       return 0x80 + WTERMSIG(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6064
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6065
       // Unknown exit code; pass it through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6066
       return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6067
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6068
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  6069
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6070
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6071
// is_headless_jre()
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6072
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  6073
// 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
  6074
// 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
  6075
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  6076
// 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
  6077
// 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
  6078
//
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6079
bool os::is_headless_jre() {
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6080
    struct stat statbuf;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6081
    char buf[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6082
    char libmawtpath[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6083
    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
  6084
    const char *new_xawtstr = "/libawt_xawt.so";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6085
    char *p;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6086
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6087
    // Get path to libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6088
    os::jvm_path(buf, sizeof(buf));
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6089
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6090
    // Get rid of libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6091
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6092
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6093
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6094
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6095
    // Get rid of client or server
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6096
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6097
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6098
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6099
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6100
    // check xawt/libmawt.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6101
    strcpy(libmawtpath, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6102
    strcat(libmawtpath, xawtstr);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6103
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6104
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  6105
    // check libawt_xawt.so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6106
    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
  6107
    strcat(libmawtpath, new_xawtstr);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6108
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6109
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6110
    return true;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6111
}
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  6112
13198
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6113
// Get the default path to the core file
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6114
// Returns the length of the string
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6115
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
  6116
  const char* p = get_current_directory(buffer, bufferSize);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6117
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6118
  if (p == NULL) {
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6119
    assert(p != NULL, "failed to get current directory");
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6120
    return 0;
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6121
  }
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6122
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6123
  return strlen(buffer);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  6124
}
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6125
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6126
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6127
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6128
// 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
  6129
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6130
MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6131
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6132
// ctor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6133
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6134
MemNotifyThread::MemNotifyThread(int fd): Thread() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6135
  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
  6136
  _fd = fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6137
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6138
  if (os::create_thread(this, os::os_thread)) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6139
    _memnotify_thread = this;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6140
    os::set_priority(this, NearMaxPriority);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6141
    os::start_thread(this);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6142
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6143
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6144
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6145
// Where all the work gets done
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6146
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6147
void MemNotifyThread::run() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6148
  assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6149
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6150
  // Set up the select arguments
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6151
  fd_set rfds;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6152
  if (_fd != -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6153
    FD_ZERO(&rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6154
    FD_SET(_fd, &rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6155
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6156
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6157
  // 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
  6158
  while (1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6159
    // 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
  6160
    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
  6161
    if (rc == -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6162
      perror("select!\n");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6163
      break;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6164
    } else if (rc) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6165
      //ssize_t free_before = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6166
      //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
  6167
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6168
      // 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
  6169
      // try to do something about that
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6170
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6171
      // 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
  6172
      if (!Universe::heap()->is_gc_active()) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6173
        Universe::heap()->collect(GCCause::_allocation_failure);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6174
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6175
        //ssize_t free_after = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6176
        //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
  6177
        //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
  6178
      }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6179
      // 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
  6180
      // 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
  6181
    }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6182
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6183
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6184
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6185
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6186
// 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
  6187
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6188
void MemNotifyThread::start() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6189
  int    fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6190
  fd = open ("/dev/mem_notify", O_RDONLY, 0);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6191
  if (fd < 0) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6192
      return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6193
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6194
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6195
  if (memnotify_thread() == NULL) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6196
    new MemNotifyThread(fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6197
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6198
}
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  6199
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  6200
#endif // JAVASE_EMBEDDED
19546
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6201
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6202
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6203
/////////////// Unit tests ///////////////
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
#ifndef PRODUCT
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
#define test_log(...) \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6208
  do {\
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6209
    if (VerboseInternalVMTests) { \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6210
      tty->print_cr(__VA_ARGS__); \
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6211
      tty->flush(); \
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
  } while (false)
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
class TestReserveMemorySpecial : AllStatic {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6216
 public:
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6217
  static void small_page_write(void* addr, size_t size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6218
    size_t page_size = os::vm_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6219
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6220
    char* end = (char*)addr + size;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6221
    for (char* p = (char*)addr; p < end; p += page_size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6222
      *p = 1;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6223
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6224
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6225
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6226
  static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6227
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6228
      return;
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
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6231
    test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6232
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6233
    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
  6234
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6235
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6236
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6237
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6238
      os::Linux::release_memory_special_huge_tlbfs(addr, size);
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
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6241
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6242
  static void test_reserve_memory_special_huge_tlbfs_only() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6243
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6244
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6245
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6246
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6247
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6248
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6249
    for (size_t size = lp; size <= lp * 10; size += lp) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6250
      test_reserve_memory_special_huge_tlbfs_only(size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6251
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6252
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6253
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6254
  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
  6255
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6256
        return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6257
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6258
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6259
    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
  6260
        size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6261
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6262
    assert(size >= os::large_page_size(), "Incorrect input to test");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6263
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6264
    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
  6265
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6266
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6267
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6268
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6269
      os::Linux::release_memory_special_huge_tlbfs(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6270
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6271
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6272
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6273
  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
  6274
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6275
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6276
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6277
    for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6278
      test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6279
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6280
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6281
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6282
  static void test_reserve_memory_special_huge_tlbfs_mixed() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6283
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6284
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6285
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6286
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6287
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6288
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6289
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6290
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6291
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6292
    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
  6293
    test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6294
    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
  6295
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6296
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6297
  static void test_reserve_memory_special_huge_tlbfs() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6298
    if (!UseHugeTLBFS) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6299
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6300
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6301
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6302
    test_reserve_memory_special_huge_tlbfs_only();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6303
    test_reserve_memory_special_huge_tlbfs_mixed();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6304
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6305
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6306
  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
  6307
    if (!UseSHM) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6308
      return;
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6309
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6310
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6311
    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
  6312
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6313
    char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6314
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6315
    if (addr != NULL) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6316
      assert(is_ptr_aligned(addr, alignment), "Check");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6317
      assert(is_ptr_aligned(addr, os::large_page_size()), "Check");
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6318
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6319
      small_page_write(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6320
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6321
      os::Linux::release_memory_special_shm(addr, size);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6322
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6323
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6324
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6325
  static void test_reserve_memory_special_shm() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6326
    size_t lp = os::large_page_size();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6327
    size_t ag = os::vm_allocation_granularity();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6328
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6329
    for (size_t size = ag; size < lp * 3; size += ag) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6330
      for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6331
        test_reserve_memory_special_shm(size, alignment);
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6332
      }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6333
    }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6334
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6335
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6336
  static void test() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6337
    test_reserve_memory_special_huge_tlbfs();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6338
    test_reserve_memory_special_shm();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6339
  }
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6340
};
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6341
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6342
void TestReserveMemorySpecial_test() {
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6343
  TestReserveMemorySpecial::test();
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6344
}
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6345
f6b7c9e96ea3 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 18683
diff changeset
  6346
#endif