hotspot/src/os/linux/vm/os_linux.cpp
author mgerdin
Thu, 22 Aug 2013 10:50:41 +0200
changeset 19726 c086d352d3f7
parent 18683 a6418e038255
child 19727 f70e36f468bb
permissions -rw-r--r--
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld Summary: When using NUMA and large pages we need to ease the requirement on which node the memory should be allocated on. To avoid the SIGBUS we now use the memory policy MPOL_PREFERRED, which prefers a certain node, instead of MPOL_BIND, which requires a certain node. Reviewed-by: jmasa, pliden Contributed-by: stefan.johansson@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
     2
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5532
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    25
// no precompiled headers
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    26
#include "classfile/classLoader.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    27
#include "classfile/systemDictionary.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    28
#include "classfile/vmSymbols.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    29
#include "code/icBuffer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    30
#include "code/vtableStubs.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    31
#include "compiler/compileBroker.hpp"
14626
0cf4eccf130f 8003240: x86: move MacroAssembler into separate file
twisti
parents: 14471
diff changeset
    32
#include "compiler/disassembler.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    33
#include "interpreter/interpreter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    34
#include "jvm_linux.h"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    35
#include "memory/allocation.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    36
#include "memory/filemap.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    37
#include "mutex_linux.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    38
#include "oops/oop.inline.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    39
#include "os_share_linux.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    40
#include "prims/jniFastGetField.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    41
#include "prims/jvm.h"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    42
#include "prims/jvm_misc.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    43
#include "runtime/arguments.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    44
#include "runtime/extendedPC.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    45
#include "runtime/globals.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    46
#include "runtime/interfaceSupport.hpp"
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
    47
#include "runtime/init.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    48
#include "runtime/java.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    49
#include "runtime/javaCalls.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    50
#include "runtime/mutexLocker.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    51
#include "runtime/objectMonitor.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    52
#include "runtime/osThread.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    53
#include "runtime/perfMemory.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    54
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    55
#include "runtime/statSampler.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    56
#include "runtime/stubRoutines.hpp"
14583
d70ee55535f4 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 14471
diff changeset
    57
#include "runtime/thread.inline.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    58
#include "runtime/threadCritical.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    59
#include "runtime/timer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    60
#include "services/attachListener.hpp"
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
    61
#include "services/memTracker.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    62
#include "services/runtimeService.hpp"
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
    63
#include "utilities/decoder.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    64
#include "utilities/defaultStream.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    65
#include "utilities/events.hpp"
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
    66
#include "utilities/elfFile.hpp"
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    67
#include "utilities/growableArray.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6964
diff changeset
    68
#include "utilities/vmError.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
// put OS-includes here
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
# include <sys/types.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
# include <sys/mman.h>
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
    73
# include <sys/stat.h>
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
    74
# include <sys/select.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
# include <pthread.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
# include <signal.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
# include <errno.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
# include <dlfcn.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
# include <stdio.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
# include <unistd.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
# include <sys/resource.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
# include <pthread.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
# include <sys/stat.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
# include <sys/time.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
# include <sys/times.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
# include <sys/utsname.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
# include <sys/socket.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
# include <sys/wait.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
# include <pwd.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
# include <poll.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
# include <semaphore.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
# include <fcntl.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
# include <string.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
# include <syscall.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
# include <sys/sysinfo.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
# include <gnu/libc-version.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
# include <sys/ipc.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
# include <sys/shm.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
# include <link.h>
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
   100
# include <stdint.h>
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
   101
# include <inttypes.h>
7458
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
   102
# include <sys/ioctl.h>
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   104
// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   105
// getrusage() is prepared to handle the associated failure.
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   106
#ifndef RUSAGE_THREAD
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   107
#define RUSAGE_THREAD   (1)               /* only the calling thread */
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   108
#endif
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
   109
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
#define MAX_PATH    (2 * K)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
// for timer info max values which include all bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
   115
#define LARGEPAGES_BIT (1 << 6)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
// global variables
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
julong os::Linux::_physical_memory = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
address   os::Linux::_initial_thread_stack_bottom = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
uintptr_t os::Linux::_initial_thread_stack_size   = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
Mutex* os::Linux::_createThread_lock = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
pthread_t os::Linux::_main_thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
int os::Linux::_page_size = -1;
17090
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
   128
const int os::Linux::_vm_default_page_size = (8 * K);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
bool os::Linux::_is_floating_stack = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
bool os::Linux::_is_NPTL = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
bool os::Linux::_supports_fast_thread_cpu_time = false;
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   132
const char * os::Linux::_glibc_version = NULL;
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   133
const char * os::Linux::_libpthread_version = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
static jlong initial_time_count=0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
static int clock_tics_per_sec = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
// For diagnostics to print a message once. see run_periodic_checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
static sigset_t check_signal_done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
static bool check_signals = true;;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
static pid_t _initial_pid = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
/* Signal number used to suspend/resume a thread */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
/* do not use any signal number less than SIGSEGV, see 4355769 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
static int SR_signum = SIGUSR2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
sigset_t SR_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   151
/* Used to protect dlsym() calls */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   152
static pthread_mutex_t dl_mutex;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
   153
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   154
// Declarations
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   155
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
   156
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   157
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   158
class MemNotifyThread: public Thread {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   159
  friend class VMStructs;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   160
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   161
  virtual void run();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   162
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   163
 private:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   164
  static MemNotifyThread* _memnotify_thread;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   165
  int _fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   166
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   167
 public:
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   168
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   169
  // Constructor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   170
  MemNotifyThread(int fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   171
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   172
  // Tester
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   173
  bool is_memnotify_thread() const { return true; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   174
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   175
  // Printing
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   176
  char* name() const { return (char*)"Linux MemNotify Thread"; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   177
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   178
  // Returns the single instance of the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   179
  static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   180
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   181
  // Create and start the single instance of MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   182
  static void start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   183
};
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   184
#endif // JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
   185
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
// utility functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
static int SR_initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
julong os::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  return Linux::available_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
julong os::Linux::available_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
  return (julong)si.freeram * si.mem_unit;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
julong os::physical_memory() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  return Linux::physical_memory();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
// environment support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
bool os::getenv(const char* name, char* buf, int len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  const char* val = ::getenv(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  if (val != NULL && strlen(val) < (size_t)len) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    strcpy(buf, val);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
  if (len > 0) buf[0] = 0;  // return a null string
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
// Return true if user is running as root.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
bool os::have_special_privileges() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  static bool init = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  static bool privileges = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  if (!init) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    privileges = (getuid() != geteuid()) || (getgid() != getegid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    init = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  return privileges;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
#ifndef SYS_gettid
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
// i386: 224, ia64: 1105, amd64: 186, sparc 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
#ifdef __ia64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
#define SYS_gettid 1105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
#elif __i386__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
#define SYS_gettid 224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
#elif __amd64__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
#define SYS_gettid 186
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
#elif __sparc__
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
#define SYS_gettid 143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
#error define gettid for the arch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
// Cpu architecture string
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   249
#if   defined(ZERO)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   250
static char cpu_arch[] = ZERO_LIBARCH;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
   251
#elif defined(IA64)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
static char cpu_arch[] = "ia64";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
#elif defined(IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
static char cpu_arch[] = "i386";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
#elif defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
static char cpu_arch[] = "amd64";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   257
#elif defined(ARM)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   258
static char cpu_arch[] = "arm";
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   259
#elif defined(PPC)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
   260
static char cpu_arch[] = "ppc";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
#elif defined(SPARC)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
#  ifdef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
static char cpu_arch[] = "sparcv9";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
#  else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
static char cpu_arch[] = "sparc";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
#  endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
#error Add appropriate cpu_arch setting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
// pid_t gettid()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
// Returns the kernel thread id of the currently running thread. Kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
// thread id is used to access /proc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
// (Note that getpid() on LinuxThreads returns kernel thread id too; but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
// on NPTL, it returns the same pid for all threads, as required by POSIX.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
pid_t os::Linux::gettid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
  int rslt = syscall(SYS_gettid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
  if (rslt == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
     // old kernel, no NPTL support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
     return getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
     return (pid_t)rslt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
// Most versions of linux have a bug where the number of processors are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
// determined by looking at the /proc file system.  In a chroot environment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
// the system call returns 1.  This causes the VM to act as if it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
// a single processor and elide locking (see is_MP() call).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
static bool unsafe_chroot_detected = false;
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   295
static const char *unstable_chroot_error = "/proc file system not found.\n"
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   296
                     "Java may be unstable running multithreaded in a chroot "
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   297
                     "environment on Linux when /proc filesystem is not mounted.";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
void os::Linux::initialize_system_info() {
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   300
  set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   301
  if (processor_count() == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
    pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
    char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
    FILE *fp = fopen(fname, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
    if (fp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
      unsafe_chroot_detected = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
  _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
4493
9204129f065e 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 4487
diff changeset
   313
  assert(processor_count() > 0, "linux error");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
void os::init_system_properties_values() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
//  char arch[12];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
//  sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
  // The next steps are taken in the product version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
  //
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   322
  // Obtain the JAVA_HOME value from the location of libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
  // This library should be located at:
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   324
  // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
  // If "/jre/lib/" appears at the right place in the path, then we
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   327
  // assume libjvm.so is installed in a JDK and we use this path.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
  // Otherwise exit with message: "Could not create the Java virtual machine."
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
  // The following extra steps are taken in the debugging version:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
  // If "/jre/lib/" does NOT appear at the right place in the path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
  // instead of exit check for $JAVA_HOME environment variable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
  // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   337
  // then we append a fake suffix "hotspot/libjvm.so" to this path so
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   338
  // it looks like libjvm.so is installed there
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
   339
  // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
  // Otherwise exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
  // Important note: if the location of libjvm.so changes this
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  // code needs to be changed accordingly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
  // The next few definitions allow the code to be verbatim:
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   347
#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
#define getenv(n) ::getenv(n)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
 * See ld(1):
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
 *      The linker uses the following search paths to locate required
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
 *      shared libraries:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
 *        1: ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
 *        ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
 *        7: The default directories, normally /lib and /usr/lib.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
 */
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   358
#if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   359
#define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   360
#else
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
#define DEFAULT_LIBPATH "/lib:/usr/lib"
1885
ae1dcaf4363f 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 1664
diff changeset
   362
#endif
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
#define EXTENSIONS_DIR  "/lib/ext"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
#define ENDORSED_DIR    "/lib/endorsed"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
#define REG_DIR         "/usr/java/packages"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    /* sysclasspath, java_home, dll_dir */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
        char *home_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
        char *dll_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
        char *pslash;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
        char buf[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
        os::jvm_path(buf, sizeof(buf));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
        // Found the full path to libjvm.so.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
        // Now cut the path to <java_home>/jre if we can.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
        *(strrchr(buf, '/')) = '\0';  /* get rid of /libjvm.so */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
        pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
        if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
            *pslash = '\0';           /* get rid of /{client|server|hotspot} */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
        dll_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
        if (dll_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
        strcpy(dll_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
        Arguments::set_dll_dir(dll_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
        if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
            pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
            if (pslash != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
                *pslash = '\0';       /* get rid of /<arch> */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
                pslash = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
                if (pslash != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
                    *pslash = '\0';   /* get rid of /lib */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
        home_path = malloc(strlen(buf) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
        if (home_path == NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
        strcpy(home_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
        Arguments::set_java_home(home_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
        if (!set_boot_path('/', ':'))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
     * Where to look for native libraries
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
     * Note: Due to a legacy implementation, most of the library path
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
     * is set in the launcher.  This was to accomodate linking restrictions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
     * on legacy Linux implementations (which are no longer supported).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
     * However, to prevent the proliferation of improperly built native
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
     * libraries, the new path component /usr/java/packages is added here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
     * Eventually, all the library path setting will be done here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
        char *ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
         * Construct the invariant part of ld_library_path. Note that the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
         * space for the colon and the trailing null are provided by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
         * nulls included by the sizeof operator (so actually we allocate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
         * a byte more than necessary).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
        ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
            strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
        sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
        /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
         * Get the user setting of LD_LIBRARY_PATH, and prepended it.  It
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
         * should always exist (until the legacy problem cited above is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
         * addressed).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
        char *v = getenv("LD_LIBRARY_PATH");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
        if (v != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
            char *t = ld_library_path;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
            /* That's +1 for the colon and +1 for the trailing '\0' */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
            ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
            sprintf(ld_library_path, "%s:%s", v, t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
        Arguments::set_library_path(ld_library_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
    /*
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
     * Extensions directories.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
     *
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
     * Note that the space for the colon and the trailing null are provided
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
     * by the nulls included by the sizeof operator (so actually one byte more
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
     * than necessary is allocated).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
     */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
        char *buf = malloc(strlen(Arguments::get_java_home()) +
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
            sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
        sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
            Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
        Arguments::set_ext_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
    /* Endorsed standards default directory. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
        char * buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
        buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
        sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
        Arguments::set_endorsed_dirs(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
#undef malloc
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
#undef getenv
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
#undef EXTENSIONS_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
#undef ENDORSED_DIR
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  // Done
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
  return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
// breakpoint support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
void os::breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
  BREAKPOINT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
extern "C" void breakpoint() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  // use debugger to set breakpoint here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
// signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
debug_only(static bool signal_sets_initialized = false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
bool os::Linux::is_sig_ignored(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
      struct sigaction oact;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
      sigaction(sig, (struct sigaction*)NULL, &oact);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
      void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*,  oact.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
                                     : CAST_FROM_FN_PTR(void*,  oact.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
      if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
      else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
           return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
void os::Linux::signal_sets_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  // Should also have an assertion stating we are still single-threaded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
  assert(!signal_sets_initialized, "Already initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
  // Fill in signals that are necessarily unblocked for all threads in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
  // the VM. Currently, we unblock the following signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  //                         by -Xrs (=ReduceSignalUsage));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // other threads. The "ReduceSignalUsage" boolean tells us not to alter
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  // the dispositions or masks wrt these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  // Programs embedding the VM that want to use the above signals for their
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
  // own purposes must, at this time, use the "-Xrs" option to prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
  // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  // (See bug 4345157, and other related bugs).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  // In reality, though, unblocking these signals is really a nop, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  // these signals are not blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  sigemptyset(&unblocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
  sigemptyset(&allowdebug_blocked_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  sigaddset(&unblocked_sigs, SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  sigaddset(&unblocked_sigs, SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  sigaddset(&unblocked_sigs, SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  sigaddset(&unblocked_sigs, SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
  sigaddset(&unblocked_sigs, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
   if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
      sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
   if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
      sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
   if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
      sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  // Fill in signals that are blocked by all but the VM thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  sigemptyset(&vm_sigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
  if (!ReduceSignalUsage)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
    sigaddset(&vm_sigs, BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  debug_only(signal_sets_initialized = true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
// These are signals that are unblocked while a thread is running Java.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
// (For some reason, they get blocked by default.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
sigset_t* os::Linux::unblocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  return &unblocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
// These are the signals that are blocked while a (non-VM) thread is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
// running Java. Only the VM thread handles these signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
sigset_t* os::Linux::vm_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
  return &vm_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
// These are signals that are blocked during cond_wait to allow debugger in
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
sigset_t* os::Linux::allowdebug_blocked_signals() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  assert(signal_sets_initialized, "Not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
  return &allowdebug_blocked_sigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
void os::Linux::hotspot_sigmask(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
  //Save caller's signal mask before setting VM signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
  sigset_t caller_sigmask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
  osthread->set_caller_sigmask(caller_sigmask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
    if (thread->is_VM_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
      // Only the VM thread handles BREAK_SIGNAL ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
      pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
      // ... all other threads block BREAK_SIGNAL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
      pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
// detecting pthread library
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
void os::Linux::libpthread_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
  // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
  // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
  // generic name for earlier versions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Define macros here so we can build HotSpot on old systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
# ifndef _CS_GNU_LIBC_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
# define _CS_GNU_LIBC_VERSION 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
# ifndef _CS_GNU_LIBPTHREAD_VERSION
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
# define _CS_GNU_LIBPTHREAD_VERSION 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
# endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
  size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   615
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
     confstr(_CS_GNU_LIBC_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
     os::Linux::set_glibc_version(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
     // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
     static char _gnu_libc_version[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
     jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
              "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
     os::Linux::set_glibc_version(_gnu_libc_version);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
  n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  if (n > 0) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
   628
     char *str = (char *)malloc(n, mtInternal);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
     confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
     // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
     // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   632
     // is the case. LinuxThreads has a hard limit on max number of threads.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   633
     // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   634
     // On the other hand, NPTL does not have such a limit, sysconf()
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   635
     // will return -1 and errno is not changed. Check if it is really NPTL.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
     if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   637
         strstr(str, "NPTL") &&
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   638
         sysconf(_SC_THREAD_THREADS_MAX) > 0) {
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   639
       free(str);
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   640
       os::Linux::set_libpthread_version("linuxthreads");
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   641
     } else {
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   642
       os::Linux::set_libpthread_version(str);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
  } else {
745
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   645
    // glibc before 2.3.2 only has LinuxThreads.
47129a5cacd3 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 388
diff changeset
   646
    os::Linux::set_libpthread_version("linuxthreads");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
  if (strstr(libpthread_version(), "NPTL")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
     os::Linux::set_is_NPTL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
     os::Linux::set_is_LinuxThreads();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
  // LinuxThreads have two flavors: floating-stack mode, which allows variable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  // stack size; and fixed-stack mode. NPTL is always floating-stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
     os::Linux::set_is_floating_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
// thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
// Force Linux kernel to expand current thread stack. If "bottom" is close
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
// to the stack guard, caller should block all signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
// MAP_GROWSDOWN:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
//   A special mmap() flag that is used to implement thread stacks. It tells
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
//   kernel that the memory region should extend downwards when needed. This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
//   allows early versions of LinuxThreads to only mmap the first few pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
//   when creating a new thread. Linux kernel will automatically expand thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
//   stack as needed (on page faults).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
//   However, because the memory region of a MAP_GROWSDOWN stack can grow on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
//   demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
//   region, it's hard to tell if the fault is due to a legitimate stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
//   access or because of reading/writing non-exist memory (e.g. buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
//   overrun). As a rule, if the fault happens below current stack pointer,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
//   Linux kernel does not expand stack, instead a SIGSEGV is sent to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
//   application (see Linux kernel fault.c).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
//   This Linux feature can cause SIGSEGV when VM bangs thread stack for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
//   stack overflow detection.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
//   Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
//   not use this flag. However, the stack of initial thread is not created
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
//   by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
//   unlikely) that user code can create a thread with MAP_GROWSDOWN stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
//   and then attach the thread to JVM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
// To get around the problem and allow stack banging on Linux, we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
// manually expand thread stack after receiving the SIGSEGV.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
// There are two ways to expand thread stack to address "bottom", we used
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
// both of them in JVM before 1.5:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
//   1. adjust stack pointer first so that it is below "bottom", and then
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
//      touch "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
//   2. mmap() the page in question
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
// Now alternate signal stack is gone, it's harder to use 2. For instance,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
// if current sp is already near the lower end of page 101, and we need to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
// call mmap() to map page 100, it is possible that part of the mmap() frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
// will be placed in page 100. When page 100 is mapped, it is zero-filled.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
// That will destroy the mmap() frame and cause VM to crash.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
// The following code works by adjusting sp first, then accessing the "bottom"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
// page to force a page fault. Linux kernel will then automatically expand the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
// stack mapping.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
// _expand_stack_to() assumes its frame size is less than page size, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
// should always be true if the function is not inlined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
#if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
#define NOINLINE
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
#else
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
#define NOINLINE __attribute__ ((noinline))
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
static void _expand_stack_to(address bottom) NOINLINE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
static void _expand_stack_to(address bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  address sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  size_t size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  volatile char *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  // Adjust bottom to point to the largest address within the same page, it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  // gives us a one-page buffer if alloca() allocates slightly more memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  bottom += os::Linux::page_size() - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  // sp might be slightly above current stack pointer; if that's the case, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  // will alloca() a little more space than necessary, which is OK. Don't use
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  // os::current_stack_pointer(), as its result can be slightly below current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  // stack pointer, causing us to not alloca enough to reach "bottom".
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  sp = (address)&sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  if (sp > bottom) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
    size = sp - bottom;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
    p = (volatile char *)alloca(size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
    assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
    p[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  assert(t!=NULL, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
  assert(t->osthread()->expanding_stack(), "expand should be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  assert(t->stack_base() != NULL, "stack_base was not initialized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  if (addr <  t->stack_base() && addr >= t->stack_yellow_zone_base()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
    sigset_t mask_all, old_sigset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
    sigfillset(&mask_all);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
    pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
    _expand_stack_to(addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
    pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
// create new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
static address highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
// check if it's safe to start a new thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
static bool _thread_safety_check(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    //   Heap is mmap'ed at lower end of memory space. Thread stacks are
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
    //   allocated (MAP_FIXED) from high address space. Every thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
    //   occupies a fixed size slot (usually 2Mbytes, but user can change
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
    //   it to other values if they rebuild LinuxThreads).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
    // Problem with MAP_FIXED is that mmap() can still succeed even part of
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
    // the memory region has already been mmap'ed. That means if we have too
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
    // many threads and/or very large heap, eventually thread stack will
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    // collide with heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    // Here we try to prevent heap/stack collision by comparing current
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
    // stack bottom with the highest address that has been mmap'ed by JVM
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    // plus a safety margin for memory maps created by native code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
    // This feature can be disabled by setting ThreadSafetyMargin to 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
    if (ThreadSafetyMargin > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
      address stack_bottom = os::current_stack_base() - os::current_stack_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
      // not safe if our stack extends below the safety margin
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
      return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    // Floating stack LinuxThreads or NPTL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
    //   Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    //   there's not enough space left, pthread_create() will fail. If we come
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
    //   here, that means enough space has been reserved for stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
// Thread start routine for all newly created threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
static void *java_start(Thread *thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
  // Try to randomize the cache line index of hot stack frames.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  // This helps when threads of the same stack traces evict each other's
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  // cache lines. The threads can be either from the same JVM instance, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  // from different JVM instances. The benefit is especially true for
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  // processors with hyperthreading technology.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  static int counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
  int pid = os::current_process_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  alloca(((pid ^ counter++) & 7) * 128);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
  ThreadLocalStorage::set_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
  Monitor* sync = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  // non floating stack LinuxThreads needs extra check, see above
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  if (!_thread_safety_check(thread)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
    osthread->set_state(ZOMBIE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
  // thread_id is kernel thread id (similar to Solaris LWP id)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  // handshaking with parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
    MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
    // notify parent thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    osthread->set_state(INITIALIZED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
    sync->notify_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
    // wait until os::start_thread()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
    while (osthread->get_state() == INITIALIZED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
      sync->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  // call one more level start routine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
  thread->run();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  assert(thread->osthread() == NULL, "caller responsible");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
  // set the correct thread state
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
  osthread->set_thread_type(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
  // Initial state is ALLOCATED but not INITIALIZED
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
  osthread->set_state(ALLOCATED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
  // init thread attributes
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  pthread_attr_t attr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  pthread_attr_init(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
  // stack size
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  if (os::Linux::supports_variable_stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
    // calculate stack size if it's not specified by caller
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
    if (stack_size == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
      stack_size = os::Linux::default_stack_size(thr_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
      switch (thr_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
      case os::java_thread:
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   894
        // Java threads use ThreadStackSize which default value can be
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   895
        // changed with the flag -Xss
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   896
        assert (JavaThread::stack_size_at_create() > 0, "this should be set");
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
   897
        stack_size = JavaThread::stack_size_at_create();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
      case os::compiler_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
        if (CompilerThreadStackSize > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
          stack_size = (size_t)(CompilerThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
        } // else fall through:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
          // use VMThreadStackSize if CompilerThreadStackSize is not defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
      case os::vm_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
      case os::pgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
      case os::cgc_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
      case os::watcher_thread:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
        if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
    stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
    pthread_attr_setstacksize(&attr, stack_size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
    // let pthread_create() pick the default value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
  // glibc guard page
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
  pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
  ThreadState state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
    // Serialize thread creation if we are running with fixed stack LinuxThreads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
    bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
      os::Linux::createThread_lock()->lock_without_safepoint_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
    pthread_t tid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
    int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
    pthread_attr_destroy(&attr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
    if (ret != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
      if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
        perror("pthread_create()");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
      // Need to clean up stuff we've allocated so far
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
      if (lock) os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
    // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
    osthread->set_pthread_id(tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
    // Wait until child thread is either initialized or aborted
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
      Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
      MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
      while ((state = osthread->get_state()) == ALLOCATED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
        sync_with_child->wait(Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
      os::Linux::createThread_lock()->unlock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  // Aborted due to thread limit being reached
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  if (state == ZOMBIE) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      thread->set_osthread(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
      delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
      return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  // The thread is returned suspended (in state INITIALIZED),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  // and is started higher up in the call chain
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  assert(state == INITIALIZED, "race condition");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
/////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
// attach existing thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
// bootstrap the main thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
bool os::create_main_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
  return create_attached_thread(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
bool os::create_attached_thread(JavaThread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    thread->verify_not_published();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  // Allocate the OSThread object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
  OSThread* osthread = new OSThread(NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
  if (osthread == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
  // Store pthread info into the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
  osthread->set_thread_id(os::Linux::gettid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
  osthread->set_pthread_id(::pthread_self());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
  // initialize floating point control register
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
  os::Linux::init_thread_fpu_state();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
  // Initial thread state is RUNNABLE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
  osthread->set_state(RUNNABLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
  thread->set_osthread(osthread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  if (UseNUMA) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    int lgrp_id = os::numa_get_group_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
    if (lgrp_id != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
      thread->set_lgrp_id(lgrp_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
  if (os::Linux::is_initial_thread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
    // If current thread is initial thread, its stack is mapped on demand,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
    // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
    // the entire stack region to avoid SEGV in stack banging.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    // It is also useful to get around the heap-stack-gap problem on SuSE
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    // kernel (see 4821821 for details). We first expand stack to the top
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
    // of yellow zone, then enable stack yellow zone (order is significant,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
    // enabling yellow zone first will crash JVM on SuSE Linux), so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
    // is no gap between the last two virtual memory regions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
    JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
    address addr = jt->stack_yellow_zone_base();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
    assert(addr != NULL, "initialization problem?");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
    osthread->set_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
    os::Linux::manually_expand_stack(jt, addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
    osthread->clear_expanding_stack();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
  // initialize signal mask for this thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
  // and save the caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
  os::Linux::hotspot_sigmask(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
void os::pd_start_thread(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
  OSThread * osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  assert(osthread->get_state() != INITIALIZED, "just checking");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  Monitor* sync_with_child = osthread->startThread_lock();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  sync_with_child->notify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
// Free Linux resources related to the OSThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
void os::free_thread(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
  assert(osthread != NULL, "osthread not set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
  if (Thread::current()->osthread() == osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
    // Restore caller's signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
    sigset_t sigmask = osthread->caller_sigmask();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
    pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  delete osthread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
// thread local storage
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
int os::allocate_thread_local_storage() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  pthread_key_t key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  int rslt = pthread_key_create(&key, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  assert(rslt == 0, "cannot allocate thread local storage");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  return (int)key;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
// Note: This is currently not used by VM, as we don't destroy TLS key
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
// on VM exit.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
void os::free_thread_local_storage(int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  int rslt = pthread_key_delete((pthread_key_t)index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  assert(rslt == 0, "invalid index");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
void os::thread_local_storage_at_put(int index, void* value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  int rslt = pthread_setspecific((pthread_key_t)index, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  assert(rslt == 0, "pthread_setspecific failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
extern "C" Thread* get_thread() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  return ThreadLocalStorage::thread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
//////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
// initial thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
// Check if current thread is the initial thread, similar to Solaris thr_main.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
bool os::Linux::is_initial_thread(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  char dummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  // If called before init complete, thread stack bottom will be null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  // Can be called if fatal error occurs before initialization.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
  if (initial_thread_stack_bottom() == NULL) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  assert(initial_thread_stack_bottom() != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
         initial_thread_stack_size()   != 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
         "os::init did not locate initial thread's stack region");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  if ((address)&dummy >= initial_thread_stack_bottom() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
      (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
       return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
  else return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
// Find the virtual memory area that contains addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
static bool find_vma(address addr, address* vma_low, address* vma_high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
  FILE *fp = fopen("/proc/self/maps", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
  if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
    address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
    while (!feof(fp)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
      if (fscanf(fp, "%p-%p", &low, &high) == 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
        if (low <= addr && addr < high) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
           if (vma_low)  *vma_low  = low;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
           if (vma_high) *vma_high = high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
           fclose (fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
           return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
      for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
        int ch = fgetc(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
        if (ch == EOF || ch == (int)'\n') break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
    fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
// Locate initial thread stack. This special handling of initial thread stack
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
// is needed because pthread_getattr_np() on most (all?) Linux distros returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
// bogus value for initial thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
void os::Linux::capture_initial_stack(size_t max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1138
  // stack size is the easy part, get it from RLIMIT_STACK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  size_t stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  struct rlimit rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  getrlimit(RLIMIT_STACK, &rlim);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
  stack_size = rlim.rlim_cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
  // 6308388: a bug in ld.so will relocate its own .data section to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
  //   lower end of primordial stack; reduce ulimit -s value a little bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  //   so we won't install guard page on ld.so's data section.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
  stack_size -= 2 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
  // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
  //   7.1, in both cases we will get 2G in return value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  //   SuSE 7.2, Debian) can not handle alternate signal stack correctly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  //   for initial thread if its stack size exceeds 6M. Cap it at 2M,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
  //   in case other parts in glibc still assumes 2M max stack size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  // FIXME: alt signal stack is gone, maybe we can relax this constraint?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
15475
73896d91270c 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 15234
diff changeset
  1157
  if (stack_size > 2 * K * K IA64_ONLY(*2))
73896d91270c 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 15234
diff changeset
  1158
      stack_size = 2 * K * K IA64_ONLY(*2);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
  // Try to figure out where the stack base (top) is. This is harder.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1161
  // When an application is started, glibc saves the initial stack pointer in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1162
  // a global variable "__libc_stack_end", which is then used by system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1163
  // libraries. __libc_stack_end should be pretty close to stack top. The
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1164
  // variable is available since the very early days. However, because it is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1165
  // a private interface, it could disappear in the future.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1166
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1167
  // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1168
  // to __libc_stack_end, it is very close to stack top, but isn't the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1169
  // stack top. Note that /proc may not exist if VM is running as a chroot
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1170
  // program, so reading /proc/<pid>/stat could fail. Also the contents of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
  // /proc/<pid>/stat could change in the future (though unlikely).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
  // We try __libc_stack_end first. If that doesn't work, look for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
  // /proc/<pid>/stat. If neither of them works, we use current stack pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  // as a hint, which should work well in most cases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  uintptr_t stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1179
  // try __libc_stack_end first
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1180
  uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1181
  if (p && *p) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1182
    stack_start = *p;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1183
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1184
    // see if we can get the start_stack field from /proc/self/stat
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1185
    FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1186
    int pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1187
    char state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1188
    int ppid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1189
    int pgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1190
    int session;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1191
    int nr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1192
    int tpgrp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1193
    unsigned long flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1194
    unsigned long minflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1195
    unsigned long cminflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1196
    unsigned long majflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1197
    unsigned long cmajflt;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1198
    unsigned long utime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1199
    unsigned long stime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1200
    long cutime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1201
    long cstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1202
    long prio;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1203
    long nice;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1204
    long junk;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1205
    long it_real;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1206
    uintptr_t start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1207
    uintptr_t vsize;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1208
    intptr_t rss;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1209
    uintptr_t rsslim;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1210
    uintptr_t scodes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1211
    uintptr_t ecode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1212
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1213
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1214
    // Figure what the primordial thread stack base is. Code is inspired
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1215
    // by email from Hans Boehm. /proc/self/stat begins with current pid,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1216
    // followed by command name surrounded by parentheses, state, etc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
    char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
    int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
    fp = fopen("/proc/self/stat", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
    if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
      statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1223
      stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
      // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
      // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
      // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
      //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
      // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1231
      // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
      char * s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
      i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
      if (s) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
        // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
        do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1238
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1239
#define _UFM UINTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1240
#define _DFM INTX_FORMAT
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1241
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1242
        /*                                     1   1   1   1   1   1   1   1   1   1   2   2    2    2    2    2    2    2    2 */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1243
        /*              3  4  5  6  7  8   9   0   1   2   3   4   5   6   7   8   9   0   1    2    3    4    5    6    7    8 */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1244
        i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
             &state,          /* 3  %c  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
             &ppid,           /* 4  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
             &pgrp,           /* 5  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
             &session,        /* 6  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
             &nr,             /* 7  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
             &tpgrp,          /* 8  %d  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
             &flags,          /* 9  %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
             &minflt,         /* 10 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
             &cminflt,        /* 11 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
             &majflt,         /* 12 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
             &cmajflt,        /* 13 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
             &utime,          /* 14 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
             &stime,          /* 15 %lu  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
             &cutime,         /* 16 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
             &cstime,         /* 17 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
             &prio,           /* 18 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
             &nice,           /* 19 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
             &junk,           /* 20 %ld  */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
             &it_real,        /* 21 %ld  */
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1264
             &start,          /* 22 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1265
             &vsize,          /* 23 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1266
             &rss,            /* 24 INTX_FORMAT  */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1267
             &rsslim,         /* 25 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1268
             &scodes,         /* 26 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1269
             &ecode,          /* 27 UINTX_FORMAT */
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1270
             &stack_start);   /* 28 UINTX_FORMAT */
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1273
#undef _UFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1274
#undef _DFM
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1275
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
      if (i != 28 - 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
         assert(false, "Bad conversion from /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
         // product mode - assume we are the initial thread, good luck in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
         // embedded case.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
         warning("Can't detect initial thread stack location - bad conversion");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
         stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
      // For some reason we can't open /proc/self/stat (for example, running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
      // FreeBSD with a Linux emulator, or inside chroot), this should work for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
      // most cases, so don't abort:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
      warning("Can't detect initial thread stack location - no /proc/self/stat");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1288
      stack_start = (uintptr_t) &rlim;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
  // Now we have a pointer (stack_start) very close to the stack top, the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
  // next thing to do is to figure out the exact location of stack top. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
  // can find out the virtual memory area that contains stack_start by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
  // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
  // and its upper limit is the real stack top. (again, this would fail if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
  // running inside chroot, because /proc may not exist.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
  uintptr_t stack_top;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
  address low, high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1301
  if (find_vma((address)stack_start, &low, &high)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    // success, "high" is the true stack top. (ignore "low", because initial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
    // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
    stack_top = (uintptr_t)high;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
    // failed, likely because /proc/self/maps does not exist
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
    warning("Can't detect initial thread stack location - find_vma failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
    // best effort: stack_start is normally within a few pages below the real
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
    // stack top, use it as stack top, and reduce stack size so we won't put
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
    // guard page outside stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
    stack_top = stack_start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
    stack_size -= 16 * page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
  // stack_top could be partially down the page so align it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
  stack_top = align_size_up(stack_top, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
  if (max_size && stack_size > max_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
     _initial_thread_stack_size = max_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1320
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
     _initial_thread_stack_size = stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
  _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
  _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
// time support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
// Time since start-up in seconds to a fine granularity.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
// Used by VMSelfDestructTimer and the MemProfiler.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
double os::elapsedTime() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
  return (double)(os::elapsed_counter()) * 0.000001;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1336
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
jlong os::elapsed_counter() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
  return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
jlong os::elapsed_frequency() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  return (1000 * 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1346
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1348
bool os::supports_vtime() { return true; }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1349
bool os::enable_vtime()   { return false; }
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1350
bool os::vtime_enabled()  { return false; }
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1351
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1352
double os::elapsedVTime() {
17854
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1353
  struct rusage usage;
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1354
  int retval = getrusage(RUSAGE_THREAD, &usage);
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1355
  if (retval == 0) {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1356
    return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1357
  } else {
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1358
    // better than nothing, but not much
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1359
    return elapsedTime();
d65bc1546091 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 17134
diff changeset
  1360
  }
1374
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1361
}
4c24294029a9 6711316: Open source the Garbage-First garbage collector
ysr
parents: 388
diff changeset
  1362
234
4da9c1bbc810 6667833: Remove CacheTimeMillis
sbohne
parents: 1
diff changeset
  1363
jlong os::javaTimeMillis() {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
  timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  return jlong(time.tv_sec) * 1000  +  jlong(time.tv_usec / 1000);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
#ifndef CLOCK_MONOTONIC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
#define CLOCK_MONOTONIC (1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
void os::Linux::clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  // we do dlopen's in this particular order due to bug in linux
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
  // dynamical loader (see 6348968) leading to crash on exit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  void* handle = dlopen("librt.so.1", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
  if (handle == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1379
    handle = dlopen("librt.so", RTLD_LAZY);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
  if (handle) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1383
    int (*clock_getres_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
    int (*clock_gettime_func)(clockid_t, struct timespec*) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
           (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
    if (clock_getres_func && clock_gettime_func) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
      // See if monotonic clock is supported by the kernel. Note that some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
      // early implementations simply return kernel jiffies (updated every
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
      // 1/100 or 1/1000 second). It would be bad to use such a low res clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
      // for nano time (though the monotonic property is still nice to have).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
      // It's fixed in newer kernels, however clock_getres() still returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
      // 1/HZ. We check if clock_getres() works, but will ignore its reported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
      // resolution for now. Hopefully as people move to new kernels, this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
      // won't be a problem.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
      struct timespec res;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
      struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
      if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
          clock_gettime_func(CLOCK_MONOTONIC, &tp)  == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
        // yes, monotonic clock is supported
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
        _clock_gettime = clock_gettime_func;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1402
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1403
        // close librt if there is no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
        dlclose(handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
#ifndef SYS_clock_getres
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
#if defined(IA32) || defined(AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
#define SYS_clock_getres IA32_ONLY(266)  AMD64_ONLY(229)
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1414
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
#else
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1416
#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1417
#define sys_clock_getres(x,y)  -1
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1420
#else
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  1421
#define sys_clock_getres(x,y)  ::syscall(SYS_clock_getres, x, y)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
void os::Linux::fast_thread_clock_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
  if (!UseLinuxPosixThreadCPUClocks) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
      (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
  // Switch to using fast clocks for thread cpu time if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  // the sys_clock_getres() returns 0 error code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
  // Note, that some kernels may support the current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  // returned by the pthread_getcpuclockid().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
  // If the fast Posix clocks are supported then the sys_clock_getres()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  // must return at least tp.tv_sec == 0 which means a resolution
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
  // better than 1 sec. This is extra check for reliability.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
  if(pthread_getcpuclockid_func &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
     pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
     sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
    _supports_fast_thread_cpu_time = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
    _pthread_getcpuclockid = pthread_getcpuclockid_func;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
jlong os::javaTimeNanos() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
    struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
    int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
    assert(status == 0, "gettime error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
    jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    timeval time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1460
    int status = gettimeofday(&time, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
    assert(status != -1, "linux error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
    jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
    return 1000 * usecs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  if (Linux::supports_monotonic_clock()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
    // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
    info_ptr->may_skip_backward = false;      // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
    info_ptr->may_skip_forward = false;       // not subject to resetting or drifting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
    // gettimeofday - based on time in seconds since the Epoch thus does not wrap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
    info_ptr->max_value = ALL_64_BITS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
    // gettimeofday is a real time clock so it skips
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
    info_ptr->may_skip_backward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    info_ptr->may_skip_forward = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
  info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
// Return the real, user, and system times in seconds from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
// arbitrary fixed point in the past.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
bool os::getTimesSecs(double* process_real_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
                      double* process_user_time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
                      double* process_system_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
  struct tms ticks;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
  clock_t real_ticks = times(&ticks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
  if (real_ticks == (clock_t) (-1)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
    double ticks_per_second = (double) clock_tics_per_sec;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
    *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
    *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
    *process_real_time = ((double) real_ticks) / ticks_per_second;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
char * os::local_time_string(char *buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
  struct tm t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
  time_t long_time;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
  time(&long_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
  localtime_r(&long_time, &t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
               t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1514
               t.tm_hour, t.tm_min, t.tm_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
2012
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1518
struct tm* os::localtime_pd(const time_t* clock, struct tm*  res) {
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1519
  return localtime_r(clock, res);
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1520
}
041fbc6030dd 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 1892
diff changeset
  1521
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1522
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
// runtime exit support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1525
// Note: os::shutdown() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
// called from signal handler. Before adding something to os::shutdown(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
void os::shutdown() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
  // allow PerfMemory to attempt cleanup of any persistent resources
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
  perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
  // needs to remove object in file system
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
  AttachListener::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
  // flush buffered output, finish log files
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
  ostream_abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1538
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
  // Check for abort hook
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
  abort_hook_t abort_hook = Arguments::abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
  if (abort_hook != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
    abort_hook();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
// Note: os::abort() might be called very early during initialization, or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
// called from signal handler. Before adding something to os::abort(), make
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
// sure it is async-safe and can handle partially initialized VM.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
void os::abort(bool dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  os::shutdown();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
  if (dump_core) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
    fdStream out(defaultStream::output_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
    out.print_raw("Current thread is ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
    char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
    out.print_raw_cr(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
    out.print_raw_cr("Dumping core ...");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
    ::abort(); // dump core
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
  ::exit(1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
// Die immediately, no exit hook, no abort hook, no cleanup.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
void os::die() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  // _exit() on LinuxThreads only kills current thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  ::abort();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
// unused on linux for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
void os::set_error_file(const char *logfile) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1576
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1577
// This method is a copy of JDK's sysGetLastErrorString
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1578
// from src/solaris/hpi/src/system_md.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1579
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1580
size_t os::lasterror(char *buf, size_t len) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1581
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1582
  if (errno == 0)  return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1583
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1584
  const char *s = ::strerror(errno);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1585
  size_t n = ::strlen(s);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1586
  if (n >= len) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1587
    n = len - 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1588
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1589
  ::strncpy(buf, s, n);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1590
  buf[n] = '\0';
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1591
  return n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1592
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  1593
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
intx os::current_thread_id() { return (intx)pthread_self(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
int os::current_process_id() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
  // Under the old linux thread library, linux gives each thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
  // its own process id. Because of this each thread will return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
  // a different pid if this method were to return the result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
  // of getpid(2). Linux provides no api that returns the pid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
  // of the launcher thread for the vm. This implementation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
  // returns a unique pid, the pid of the launcher thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
  // that starts the vm 'process'.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
  // Under the NPTL, getpid() returns the same pid as the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
  // launcher thread rather than a unique pid per thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
  // Use gettid() if you want the old pre NPTL behaviour.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
  // if you are looking for the result of a call to getpid() that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
  // returns a unique pid for the calling thread, then look at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
  // OSThread::thread_id() method in osThread_linux.hpp file
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
  return (int)(_initial_pid ? _initial_pid : getpid());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
// DLL functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
const char* os::dll_file_extension() { return ".so"; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
7901
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1620
// This must be hard coded because it's the system's temporary
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1621
// directory not the java application's temp directory, ala java.io.tmpdir.
ea3d83447861 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 7458
diff changeset
  1622
const char* os::get_temp_directory() { return "/tmp"; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1624
static bool file_exists(const char* filename) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1625
  struct stat statbuf;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1626
  if (filename == NULL || strlen(filename) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1627
    return false;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1628
  }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1629
  return os::stat(filename, &statbuf) == 0;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1630
}
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1631
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1632
bool os::dll_build_name(char* buffer, size_t buflen,
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1633
                        const char* pname, const char* fname) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1634
  bool retval = false;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1635
  // Copied from libhpi
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1636
  const size_t pnamelen = pname ? strlen(pname) : 0;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1637
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1638
  // Return error on buffer overflow.
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1639
  if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1640
    return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1641
  }
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1642
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1643
  if (pnamelen == 0) {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1644
    snprintf(buffer, buflen, "lib%s.so", fname);
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1645
    retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1646
  } else if (strchr(pname, *os::path_separator()) != NULL) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1647
    int n;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1648
    char** pelements = split_path(pname, &n);
16669
fb3397cee116 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 16438
diff changeset
  1649
    if (pelements == NULL) {
16672
dcubed
parents: 16609 16670
diff changeset
  1650
      return false;
16669
fb3397cee116 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 16438
diff changeset
  1651
    }
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1652
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1653
      // Really shouldn't be NULL, but check can't hurt
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1654
      if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1655
        continue; // skip the empty path values
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1656
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1657
      snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1658
      if (file_exists(buffer)) {
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1659
        retval = true;
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1660
        break;
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1661
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1662
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1663
    // release the storage
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1664
    for (int i = 0 ; i < n ; i++) {
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1665
      if (pelements[i] != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1666
        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1667
      }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1668
    }
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1669
    if (pelements != NULL) {
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  1670
      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1671
    }
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1672
  } else {
2358
7c8346929fc6 6819213: revive sun.boot.library.path
phh
parents: 2268
diff changeset
  1673
    snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
14471
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1674
    retval = true;
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1675
  }
f3a6b82e25cf 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 13932
diff changeset
  1676
  return retval;
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1677
}
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  1678
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  1679
// check if addr is inside libjvm.so
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
bool os::address_is_in_vm(address addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
  static address libjvm_base_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
  if (libjvm_base_addr == NULL) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1685
    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1686
      libjvm_base_addr = (address)dlinfo.dli_fbase;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1687
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
    assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1691
  if (dladdr((void *)addr, &dlinfo) != 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
bool os::dll_address_to_function_name(address addr, char *buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
                                      int buflen, int *offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1700
  // buf is not optional, but offset is optional
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1701
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1702
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1705
  if (dladdr((void*)addr, &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1706
    // see if we have a matching symbol
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1707
    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1708
      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1709
        jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1710
      }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1711
      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1712
      return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1713
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1714
    // no matching symbol so try for just file info
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1715
    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1716
      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1717
                          buf, buflen, offset, dlinfo.dli_fname)) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1718
        return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1719
      }
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1720
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1721
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1722
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1723
  buf[0] = '\0';
7447
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1724
  if (offset != NULL) *offset = -1;
32c42d627f41 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 7397
diff changeset
  1725
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
struct _address_to_library_name {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  address addr;          // input : memory address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  size_t  buflen;        //         size of fname
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  char*   fname;         // output: library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  address base;          //         library base addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
static int address_to_library_name_callback(struct dl_phdr_info *info,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1736
                                            size_t size, void *data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1737
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1738
  bool found = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
  address libbase = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1740
  struct _address_to_library_name * d = (struct _address_to_library_name *)data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  // iterate through all loadable segments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1743
  for (i = 0; i < info->dlpi_phnum; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1744
    address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
    if (info->dlpi_phdr[i].p_type == PT_LOAD) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1746
      // base address of a library is the lowest address of its loaded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
      // segments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
      if (libbase == NULL || libbase > segbase) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
        libbase = segbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
      // see if 'addr' is within current segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
      if (segbase <= d->addr &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
          d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
        found = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
  // dlpi_name is NULL or empty if the ELF file is executable, return 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
  // so dll_address_to_library_name() can fall through to use dladdr() which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
  // can figure out executable name from argv[0].
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
  if (found && info->dlpi_name && info->dlpi_name[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
    d->base = libbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
    if (d->fname) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
      jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
    return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
bool os::dll_address_to_library_name(address addr, char* buf,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
                                     int buflen, int* offset) {
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1774
  // buf is not optional, but offset is optional
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1775
  assert(buf != NULL, "sanity check");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1776
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1777
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
  struct _address_to_library_name data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1780
  // There is a bug in old glibc dladdr() implementation that it could resolve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1781
  // to wrong library name if the .so file has a base address != NULL. Here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1782
  // we iterate through the program headers of all loaded libraries to find
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1783
  // out which library 'addr' really belongs to. This workaround can be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1784
  // removed once the minimum requirement for glibc is moved to 2.3.x.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1785
  data.addr = addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1786
  data.fname = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1787
  data.buflen = buflen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1788
  data.base = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1791
  if (rslt) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
     // buf already contains library name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
     if (offset) *offset = addr - data.base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
     return true;
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1795
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1796
  if (dladdr((void*)addr, &dlinfo) != 0) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1797
    if (dlinfo.dli_fname != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1798
      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1799
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1800
    if (dlinfo.dli_fbase != NULL && offset != NULL) {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1801
      *offset = addr - (address)dlinfo.dli_fbase;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1802
    }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1803
    return true;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1804
  }
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1805
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1806
  buf[0] = '\0';
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1807
  if (offset) *offset = -1;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  1808
  return false;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
  // Loads .dll/.so and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  // in case of error it checks if .dll/.so was built for the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
  // same architecture as Hotspot is running on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1815
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1816
// Remember the stack's state. The Linux dynamic linker will change
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1817
// the stack to 'executable' at most once, so we must safepoint only once.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1818
bool os::Linux::_stack_is_executable = false;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1819
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1820
// VM operation that loads a library.  This is necessary if stack protection
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1821
// of the Java stacks can be lost during loading the library.  If we
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1822
// do not stop the Java threads, they can stack overflow before the stacks
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1823
// are protected again.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1824
class VM_LinuxDllLoad: public VM_Operation {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1825
 private:
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1826
  const char *_filename;
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1827
  char *_ebuf;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1828
  int _ebuflen;
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1829
  void *_lib;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1830
 public:
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1831
  VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) :
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1832
    _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {}
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1833
  VMOp_Type type() const { return VMOp_LinuxDllLoad; }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1834
  void doit() {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1835
    _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1836
    os::Linux::_stack_is_executable = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1837
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1838
  void* loaded_library() { return _lib; }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1839
};
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1840
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
{
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1843
  void * result = NULL;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1844
  bool load_attempted = false;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1845
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1846
  // Check whether the library to load might change execution rights
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1847
  // of the stack. If they are changed, the protection of the stack
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1848
  // guard pages will be lost. We need a safepoint to fix this.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1849
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1850
  // See Linux man page execstack(8) for more info.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1851
  if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1852
    ElfFile ef(filename);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1853
    if (!ef.specifies_noexecstack()) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1854
      if (!is_init_completed()) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1855
        os::Linux::_stack_is_executable = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1856
        // This is OK - No Java threads have been created yet, and hence no
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1857
        // stack guard pages to fix.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1858
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1859
        // This should happen only when you are building JDK7 using a very
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1860
        // old version of JDK6 (e.g., with JPRT) and running test_gamma.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1861
        //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1862
        // Dynamic loader will make all stacks executable after
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1863
        // this function returns, and will not do that again.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1864
        assert(Threads::first() == NULL, "no Java threads should exist yet.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1865
      } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1866
        warning("You have loaded library %s which might have disabled stack guard. "
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1867
                "The VM will try to fix the stack guard now.\n"
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1868
                "It's highly recommended that you fix the library with "
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1869
                "'execstack -c <libfile>', or link it with '-z noexecstack'.",
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1870
                filename);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1871
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1872
        assert(Thread::current()->is_Java_thread(), "must be Java thread");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1873
        JavaThread *jt = JavaThread::current();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1874
        if (jt->thread_state() != _thread_in_native) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1875
          // This happens when a compiler thread tries to load a hsdis-<arch>.so file
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1876
          // that requires ExecStack. Cannot enter safe point. Let's give up.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1877
          warning("Unable to fix stack guard. Giving up.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1878
        } else {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1879
          if (!LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1880
            // This is for the case where the DLL has an static
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1881
            // constructor function that executes JNI code. We cannot
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1882
            // load such DLLs in the VMThread.
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1883
            result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1884
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1885
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1886
          ThreadInVMfromNative tiv(jt);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1887
          debug_only(VMNativeEntryWrapper vew;)
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1888
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1889
          VM_LinuxDllLoad op(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1890
          VMThread::execute(&op);
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1891
          if (LoadExecStackDllInVMThread) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1892
            result = op.loaded_library();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1893
          }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1894
          load_attempted = true;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1895
        }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1896
      }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1897
    }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1898
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1899
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1900
  if (!load_attempted) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  1901
    result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1902
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  1903
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
  if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
    // Successful loading
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
    return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  Elf32_Ehdr elf_head;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  int diag_msg_max_length=ebuflen-strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  char* diag_msg_buf=ebuf+strlen(ebuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  if (diag_msg_max_length==0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
    // No more space in ebuf for additional diagnostics message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
  int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
  if (file_descriptor < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
    // Can't open library, report dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1925
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  bool failed_to_read_elf_head=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
    (sizeof(elf_head)!=
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
        (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
  ::close(file_descriptor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  if (failed_to_read_elf_head) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
    // file i/o error - report dlerror() msg
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
  typedef struct {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
    Elf32_Half  code;         // Actual value as defined in elf.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
    Elf32_Half  compat_class; // Compatibility of archs at VM's sense
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
    char        elf_class;    // 32 or 64 bit
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
    char        endianess;    // MSB or LSB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    char*       name;         // String representation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  } arch_t;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
  #ifndef EM_486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
  #define EM_486          6               /* Intel 80486 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
  static const arch_t arch_array[]={
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
    {EM_386,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
    {EM_486,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
    {EM_IA_64,       EM_IA_64,   ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
    {EM_X86_64,      EM_X86_64,  ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
    {EM_SPARC,       EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    {EM_SPARC32PLUS, EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    {EM_SPARCV9,     EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    {EM_PPC,         EM_PPC,     ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1957
    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1958
    {EM_ARM,         EM_ARM,     ELFCLASS32,   ELFDATA2LSB, (char*)"ARM"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1959
    {EM_S390,        EM_S390,    ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1960
    {EM_ALPHA,       EM_ALPHA,   ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1961
    {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1962
    {EM_MIPS,        EM_MIPS,    ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1963
    {EM_PARISC,      EM_PARISC,  ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1964
    {EM_68K,         EM_68K,     ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1965
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  #if  (defined IA32)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
    static  Elf32_Half running_arch_code=EM_386;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1969
  #elif   (defined AMD64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
    static  Elf32_Half running_arch_code=EM_X86_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
  #elif  (defined IA64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1972
    static  Elf32_Half running_arch_code=EM_IA_64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1973
  #elif  (defined __sparc) && (defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1974
    static  Elf32_Half running_arch_code=EM_SPARCV9;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1975
  #elif  (defined __sparc) && (!defined _LP64)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1976
    static  Elf32_Half running_arch_code=EM_SPARC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1977
  #elif  (defined __powerpc64__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1978
    static  Elf32_Half running_arch_code=EM_PPC64;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
  #elif  (defined __powerpc__)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
    static  Elf32_Half running_arch_code=EM_PPC;
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1981
  #elif  (defined ARM)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1982
    static  Elf32_Half running_arch_code=EM_ARM;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1983
  #elif  (defined S390)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1984
    static  Elf32_Half running_arch_code=EM_S390;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1985
  #elif  (defined ALPHA)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1986
    static  Elf32_Half running_arch_code=EM_ALPHA;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1987
  #elif  (defined MIPSEL)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1988
    static  Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1989
  #elif  (defined PARISC)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1990
    static  Elf32_Half running_arch_code=EM_PARISC;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1991
  #elif  (defined MIPS)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1992
    static  Elf32_Half running_arch_code=EM_MIPS;
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1993
  #elif  (defined M68K)
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1994
    static  Elf32_Half running_arch_code=EM_68K;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1995
  #else
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1996
    #error Method os::dll_load requires that one of following is defined:\
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  1997
         IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
  #endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1999
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
  // Identify compatability class for VM's architecture and library's architecture
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
  // Obtain string descriptions for architectures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2002
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2003
  arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2004
  int running_arch_index=-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
    if (running_arch_code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
      running_arch_index    = i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
    if (lib_arch.code == arch_array[i].code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
      lib_arch.compat_class = arch_array[i].compat_class;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
      lib_arch.name         = arch_array[i].name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  assert(running_arch_index != -1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
    "Didn't find running architecture code (running_arch_code) in arch_array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  if (running_arch_index == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
    // Even though running architecture detection failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
    // we may still continue with reporting dlerror() message
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
  if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2029
#ifndef S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
  if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
  }
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  2034
#endif // !S390
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
  if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
    if ( lib_arch.name!=NULL ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
        " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
        lib_arch.name, arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
      " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
        lib_arch.code,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2045
        arch_array[running_arch_index].name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2046
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2052
void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2053
  void * result = ::dlopen(filename, RTLD_LAZY);
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2054
  if (result == NULL) {
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2055
    ::strncpy(ebuf, ::dlerror(), ebuflen - 1);
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2056
    ebuf[ebuflen-1] = '\0';
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2057
  }
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2058
  return result;
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2059
}
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2060
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2061
void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) {
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2062
  void * result = NULL;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2063
  if (LoadExecStackDllInVMThread) {
16438
245d5c0a8dd8 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 15927
diff changeset
  2064
    result = dlopen_helper(filename, ebuf, ebuflen);
15926
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2065
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2066
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2067
  // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2068
  // library that requires an executable stack, or which does not have this
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2069
  // stack attribute set, dlopen changes the stack attribute to executable. The
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2070
  // read protection of the guard pages gets lost.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2071
  //
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2072
  // Need to check _stack_is_executable again as multiple VM_LinuxDllLoad
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2073
  // may have been queued at the same time.
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2074
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2075
  if (!_stack_is_executable) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2076
    JavaThread *jt = Threads::first();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2077
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2078
    while (jt) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2079
      if (!jt->stack_guard_zone_unused() &&        // Stack not yet fully initialized
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2080
          jt->stack_yellow_zone_enabled()) {       // No pending stack overflow exceptions
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2081
        if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2082
                              jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2083
          warning("Attempt to reguard stack yellow zone failed.");
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2084
        }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2085
      }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2086
      jt = jt->next();
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2087
    }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2088
  }
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2089
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2090
  return result;
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2091
}
8e87d545195f 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 15855
diff changeset
  2092
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2093
/*
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2094
 * glibc-2.0 libdl is not MT safe.  If you are building with any glibc,
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2095
 * chances are you might want to run the generated bits against glibc-2.0
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2096
 * libdl.so, so always use locking for any version of glibc.
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2097
 */
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2098
void* os::dll_lookup(void* handle, const char* name) {
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2099
  pthread_mutex_lock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2100
  void* res = dlsym(handle, name);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2101
  pthread_mutex_unlock(&dl_mutex);
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2102
  return res;
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  2103
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2106
static bool _print_ascii_file(const char* filename, outputStream* st) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2107
  int fd = ::open(filename, O_RDONLY);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
  if (fd == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
     return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
  char buf[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
  int bytes;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2114
  while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
    st->print_raw(buf, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2118
  ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
void os::print_dll_info(outputStream *st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
   st->print_cr("Dynamic libraries:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
   char fname[32];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
   pid_t pid = os::Linux::gettid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
   jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
   if (!_print_ascii_file(fname, st)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
     st->print("Can not get library information for pid = %d\n", pid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2136
void os::print_os_info_brief(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2137
  os::Linux::print_distro_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2138
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2139
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2140
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2141
  os::Linux::print_libversion_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2142
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2143
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2145
void os::print_os_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2146
  st->print("OS:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2147
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2148
  os::Linux::print_distro_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2149
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2150
  os::Posix::print_uname_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2151
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2152
  // Print warning if unsafe chroot environment detected
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2153
  if (unsafe_chroot_detected) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2154
    st->print("WARNING!! ");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2155
    st->print_cr(unstable_chroot_error);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2156
  }
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2157
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2158
  os::Linux::print_libversion_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2159
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2160
  os::Posix::print_rlimit_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2161
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2162
  os::Posix::print_load_average(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2163
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2164
  os::Linux::print_full_memory_info(st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2165
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2166
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2167
// Try to identify popular distros.
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2168
// Most Linux distributions have /etc/XXX-release file, which contains
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2169
// the OS version string. Some have more than one /etc/XXX-release file
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2170
// (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2171
// so the order is important.
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2172
void os::Linux::print_distro_info(outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
  if (!_print_ascii_file("/etc/mandrake-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
      !_print_ascii_file("/etc/sun-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
      !_print_ascii_file("/etc/redhat-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
      !_print_ascii_file("/etc/SuSE-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
      !_print_ascii_file("/etc/turbolinux-release", st) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
      !_print_ascii_file("/etc/gentoo-release", st) &&
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2179
      !_print_ascii_file("/etc/debian_version", st) &&
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2180
      !_print_ascii_file("/etc/ltib-release", st) &&
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2181
      !_print_ascii_file("/etc/angstrom-version", st)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
      st->print("Linux");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
  st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2185
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2186
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2187
void os::Linux::print_libversion_info(outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  // libc, pthread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  st->print("libc:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
  st->print(os::Linux::glibc_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
  st->print(os::Linux::libpthread_version()); st->print(" ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
  if (os::Linux::is_LinuxThreads()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
     st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
  st->cr();
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2196
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2197
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2198
void os::Linux::print_full_memory_info(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2199
   st->print("\n/proc/meminfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2200
   _print_ascii_file("/proc/meminfo", st);
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2201
   st->cr();
10023
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2202
}
e99d9a03c0f5 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 9625
diff changeset
  2203
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
void os::print_memory_info(outputStream* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
  st->print("Memory:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
  st->print(" %dk page", os::vm_page_size()>>10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
  // values in struct sysinfo are "unsigned long"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
  struct sysinfo si;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
  sysinfo(&si);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
  st->print(", physical " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
            os::physical_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
            os::available_memory() >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
  st->print(", swap " UINT64_FORMAT "k",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
            ((jlong)si.totalswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
  st->print("(" UINT64_FORMAT "k free)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
            ((jlong)si.freeswap * si.mem_unit) >> 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
12735
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2224
void os::pd_print_cpu_info(outputStream* st) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2225
  st->print("\n/proc/cpuinfo:\n");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2226
  if (!_print_ascii_file("/proc/cpuinfo", st)) {
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2227
    st->print("  <Not Available>");
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2228
  }
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2229
  st->cr();
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2230
}
3e2e491f4f69 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 12116
diff changeset
  2231
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
// Taken from /usr/include/bits/siginfo.h  Supposed to be architecture specific
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
// but they're the same for all the linux arch that we support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
// and they're the same for solaris but there's no common place to put this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
                          "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
                          "ILL_COPROC", "ILL_BADSTK" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
                          "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
                          "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
void os::print_siginfo(outputStream* st, void* siginfo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
  st->print("siginfo:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
  const int buflen = 100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
  char buf[buflen];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
  siginfo_t *si = (siginfo_t*)siginfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
  st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
  if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
    st->print("si_errno=%s", buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
    st->print("si_errno=%d", si->si_errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
  const int c = si->si_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
  assert(c > 0, "unexpected si_code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
  switch (si->si_signo) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
    st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
    st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
    st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2273
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
    st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
    st->print(", si_code=%d", si->si_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
    // no si_addr
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
      UseSharedSpaces) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
    FileMapInfo* mapinfo = FileMapInfo::current_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
    if (mapinfo->is_in_shared_space(si->si_addr)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
      st->print("\n\nError accessing class data sharing archive."   \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
                " Mapped file inaccessible during execution, "      \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
                " possible disk/network problem.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
                                 char* buf, size_t buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
  st->print_cr("Signal Handlers:");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
  print_signal_handler(st, SIGSEGV, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
  print_signal_handler(st, SIGBUS , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
  print_signal_handler(st, SIGFPE , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  print_signal_handler(st, SIGPIPE, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
  print_signal_handler(st, SIGXFSZ, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
  print_signal_handler(st, SIGILL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  print_signal_handler(st, SR_signum, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
static char saved_jvm_path[MAXPATHLEN] = {0};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2317
// Find the full path to the current module, libjvm.so
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2318
void os::jvm_path(char *buf, jint buflen) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
  // Error checking.
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2320
  if (buflen < MAXPATHLEN) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
    assert(false, "must use a large-enough buffer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
    buf[0] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
  // Lazy resolve the path to current module.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
  if (saved_jvm_path[0] != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
    strcpy(buf, saved_jvm_path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
  char dli_fname[MAXPATHLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
  bool ret = dll_address_to_library_name(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
                CAST_FROM_FN_PTR(address, os::jvm_path),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
                dli_fname, sizeof(dli_fname), NULL);
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2335
  assert(ret, "cannot locate libjvm");
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2336
  char *rp = NULL;
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2337
  if (ret && dli_fname[0] != '\0') {
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2338
    rp = realpath(dli_fname, buf);
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  2339
  }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2340
  if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2341
    return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
8476
7e34c2d4cf9b 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 8119
diff changeset
  2343
  if (Arguments::created_by_gamma_launcher()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
    // Support for the gamma launcher.  Typical value for buf is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
    // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
    // the right place in the string, then assume we are installed in a JDK and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
    // we're done.  Otherwise, check for a JAVA_HOME environment variable and fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
    // up the path so it looks like libjvm.so is installed there (append a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
    // fake suffix hotspot/libjvm.so).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
    const char *p = buf + strlen(buf) - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
    for (int count = 0; p > buf && count < 5; ++count) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
      for (--p; p > buf && *p != '/'; --p)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
        /* empty */ ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
    if (strncmp(p, "/jre/lib/", 9) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
      // Look for JAVA_HOME in the environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      char* java_home_var = ::getenv("JAVA_HOME");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      if (java_home_var != NULL && java_home_var[0] != 0) {
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2360
        char* jrelib_p;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2361
        int len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2362
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2363
        // Check the current module name "libjvm.so".
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
        p = strrchr(buf, '/');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
        assert(strstr(p, "/libjvm") == p, "invalid library name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2367
        rp = realpath(java_home_var, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2368
        if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2369
          return;
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2370
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2371
        // determine if this is a legacy image or modules image
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2372
        // modules image doesn't have "jre" subdirectory
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2373
        len = strlen(buf);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2374
        jrelib_p = buf + len;
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2375
        snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2376
        if (0 != access(buf, F_OK)) {
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2377
          snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2378
        }
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2379
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
        if (0 == access(buf, F_OK)) {
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2381
          // Use current module name "libjvm.so"
5922
883ecb03d008 6967423: Hotspot support for modules image
mchung
parents: 5547
diff changeset
  2382
          len = strlen(buf);
15096
3db45569f8c0 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 14633
diff changeset
  2383
          snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
          // Go back to path of .so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2386
          rp = realpath(dli_fname, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2387
          if (rp == NULL)
1889
24b003a6fe46 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 1664
diff changeset
  2388
            return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
  strcpy(saved_jvm_path, buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
  // no prefix required, not even "_"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
  // no suffix required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
// sun.misc.Signal support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
static volatile jint sigint_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
static void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
UserHandler(int sig, void *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
  // 4511530 - sem_post is serialized and handled by the manager thread. When
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
  // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
  // don't want to flood the manager thread with sem_post requests.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
  if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
  // Ctrl-C is pressed during error reporting, likely because the error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
  // handler fails to abort. Let VM die immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
  if (sig == SIGINT && is_error_reported()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
     os::die();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
  os::signal_notify(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
void* os::user_handler() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
  return CAST_FROM_FN_PTR(void*, UserHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2431
class Semaphore : public StackObj {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2432
  public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2433
    Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2434
    ~Semaphore();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2435
    void signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2436
    void wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2437
    bool trywait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2438
    bool timedwait(unsigned int sec, int nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2439
  private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2440
    sem_t _semaphore;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2441
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2442
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2443
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2444
Semaphore::Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2445
  sem_init(&_semaphore, 0, 0);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2446
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2447
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2448
Semaphore::~Semaphore() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2449
  sem_destroy(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2450
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2451
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2452
void Semaphore::signal() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2453
  sem_post(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2454
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2455
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2456
void Semaphore::wait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2457
  sem_wait(&_semaphore);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2458
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2459
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2460
bool Semaphore::trywait() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2461
  return sem_trywait(&_semaphore) == 0;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2462
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2463
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2464
bool Semaphore::timedwait(unsigned int sec, int nsec) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2465
  struct timespec ts;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2466
  unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2467
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2468
  while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2469
    int result = sem_timedwait(&_semaphore, &ts);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2470
    if (result == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2471
      return true;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2472
    } else if (errno == EINTR) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2473
      continue;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2474
    } else if (errno == ETIMEDOUT) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2475
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2476
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2477
      return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2478
    }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2479
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2480
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2481
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
  typedef void (*sa_handler_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
  typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
void* os::signal(int signal_number, void* handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
  struct sigaction sigAct, oldSigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
  sigAct.sa_flags   = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
  sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
  if (sigaction(signal_number, &sigAct, &oldSigAct)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
    // -1 means registration failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
    return (void *)-1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
  return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
void os::signal_raise(int signal_number) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
  ::raise(signal_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
 * The following code is moved from os.cpp for making this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
 * code platform specific, which it is by its very nature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
// Will be modified when max signal is changed to be dynamic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
int os::sigexitnum_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
  return NSIG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
// a counter for each possible signal value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
static volatile jint pending_signals[NSIG+1] = { 0 };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
// Linux(POSIX) specific hand shaking semaphore.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
static sem_t sig_sem;
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  2521
static Semaphore sr_semaphore;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
void os::signal_init_pd() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
  // Initialize signal structures
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
  ::memset((void*)pending_signals, 0, sizeof(pending_signals));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
  // Initialize signal semaphore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
  ::sem_init(&sig_sem, 0, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2531
void os::signal_notify(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
  Atomic::inc(&pending_signals[sig]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
  ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
static int check_pending_signals(bool wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
  Atomic::store(0, &sigint_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
    for (int i = 0; i < NSIG + 1; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
      jint n = pending_signals[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
        return i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
    if (!wait) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
      return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
    JavaThread *thread = JavaThread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
    ThreadBlockInVM tbivm(thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
    bool threadIsSuspended;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
      thread->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
      ::sem_wait(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
      // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
      if (threadIsSuspended) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
        // The semaphore has been incremented, but while we were waiting
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
        // another thread suspended us. We don't want to continue running
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
        // while suspended because that would surprise the thread that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
        // suspended us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
        //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
        ::sem_post(&sig_sem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
        thread->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
    } while (threadIsSuspended);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
int os::signal_lookup() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
  return check_pending_signals(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
int os::signal_wait() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
  return check_pending_signals(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
// Virtual Memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
int os::vm_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  // Seems redundant as all get out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
// Solaris allocates memory by pages.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
int os::vm_allocation_granularity() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
  assert(os::Linux::page_size() != -1, "must call os::init");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
  return os::Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
// Rationale behind this function:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
//  current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
//  mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
//  samples for JITted code. Here we create private executable mapping over the code cache
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
//  and then we can use standard (well, almost, as mapping can change) way to provide
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
//  info for the reporting script by storing timestamp and location of symbol
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
void linux_wrap_code(char* base, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
  static volatile jint cnt = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
  if (!UseOprofile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
5410
c4b979417733 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 5237
diff changeset
  2610
  char buf[PATH_MAX+1];
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
  int num = Atomic::add(1, &cnt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
5237
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5090
diff changeset
  2613
  snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
aab592fd4f44 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 5090
diff changeset
  2614
           os::get_temp_directory(), os::current_process_id(), num);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
  unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2617
  int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  if (fd != -1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2620
    off_t rv = ::lseek(fd, size-2, SEEK_SET);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
    if (rv != (off_t)-1) {
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2622
      if (::write(fd, "", 1) == 1) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
        mmap(base, size,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
             PROT_READ|PROT_WRITE|PROT_EXEC,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
             MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  2628
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
    unlink(buf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2633
static bool recoverable_mmap_error(int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2634
  // See if the error is one we can let the caller handle. This
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2635
  // list of errno values comes from JBS-6843484. I can't find a
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2636
  // Linux man page that documents this specific set of errno
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2637
  // values so while this list currently matches Solaris, it may
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2638
  // change as we gain experience with this failure mode.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2639
  switch (err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2640
  case EBADF:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2641
  case EINVAL:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2642
  case ENOTSUP:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2643
    // let the caller deal with these errors
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2644
    return true;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2645
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2646
  default:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2647
    // Any remaining errors on this OS can cause our reserved mapping
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2648
    // to be lost. That can cause confusion where different data
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2649
    // structures think they have the same memory mapped. The worst
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2650
    // scenario is if both the VM and a library think they have the
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2651
    // same memory mapped.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2652
    return false;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2653
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2654
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2655
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2656
static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2657
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2658
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2659
          ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2660
          strerror(err), err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2661
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2662
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2663
static void warn_fail_commit_memory(char* addr, size_t size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2664
                                    size_t alignment_hint, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2665
                                    int err) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2666
  warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2667
          ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2668
          alignment_hint, exec, strerror(err), err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2669
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2670
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
// NOTE: Linux kernel does not really reserve the pages for us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
//       All it does is to check if there are enough free pages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
//       left at the time of mmap(). This could be a potential
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
//       problem.
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2675
int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
2268
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  2676
  int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  2677
  uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
                                   MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2679
  if (res != (uintptr_t) MAP_FAILED) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2680
    if (UseNUMAInterleaving) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2681
      numa_make_global(addr, size);
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2682
    }
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2683
    return 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2684
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2685
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2686
  int err = errno;  // save errno from mmap() call above
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2687
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2688
  if (!recoverable_mmap_error(err)) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2689
    warn_fail_commit_memory(addr, size, exec, err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2690
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2691
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2692
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2693
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2694
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2695
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2696
bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2697
  return os::Linux::commit_memory_impl(addr, size, exec) == 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2698
}
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2699
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2700
void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2701
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2702
  assert(mesg != NULL, "mesg must be specified");
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2703
  int err = os::Linux::commit_memory_impl(addr, size, exec);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2704
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2705
    // the caller wants all commit errors to exit with the specified mesg:
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2706
    warn_fail_commit_memory(addr, size, exec, err);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2707
    vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2708
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2711
// Define MAP_HUGETLB here so we can build HotSpot on old systems.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2712
#ifndef MAP_HUGETLB
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2713
#define MAP_HUGETLB 0x40000
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2714
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2715
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2716
// Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2717
#ifndef MADV_HUGEPAGE
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2718
#define MADV_HUGEPAGE 14
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2719
#endif
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2720
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2721
int os::Linux::commit_memory_impl(char* addr, size_t size,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2722
                                  size_t alignment_hint, bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2723
  int err;
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2724
  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2725
    int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2726
    uintptr_t res =
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2727
      (uintptr_t) ::mmap(addr, size, prot,
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2728
                         MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2729
                         -1, 0);
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2730
    if (res != (uintptr_t) MAP_FAILED) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2731
      if (UseNUMAInterleaving) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2732
        numa_make_global(addr, size);
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2733
      }
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2734
      return 0;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2735
    }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2736
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2737
    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
  2738
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2739
    if (!recoverable_mmap_error(err)) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2740
      // However, it is not clear that this loss of our reserved mapping
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2741
      // happens with large pages on Linux or that we cannot recover
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2742
      // from the loss. For now, we just issue a warning and we don't
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2743
      // call vm_exit_out_of_memory(). This issue is being tracked by
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2744
      // JBS-8007074.
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2745
      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
  2746
//    vm_exit_out_of_memory(size, OOM_MMAP_ERROR,
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2747
//                          "committing reserved memory.");
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  2748
    }
10522
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2749
    // Fall through and try to use small pages
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2750
  }
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2751
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2752
  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
  2753
  if (err == 0) {
10522
23830453e083 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 10496
diff changeset
  2754
    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
  2755
  }
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2756
  return err;
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2757
}
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
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
  2760
                          bool exec) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2761
  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
  2762
}
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
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
  2765
                                  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
  2766
                                  const char* mesg) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2767
  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
  2768
  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
  2769
  if (err != 0) {
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2770
    // 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
  2771
    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
  2772
    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
  2773
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2776
void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2777
  if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2778
    // 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
  2779
    // 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
  2780
    ::madvise(addr, bytes, MADV_HUGEPAGE);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2781
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  2782
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2783
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2784
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
  2785
  // 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
  2786
  // 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
  2787
  // 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
  2788
  // 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
  2789
  // allow that in any case.
d81396ae8bf6 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 11967
diff changeset
  2790
  if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  2791
    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
  2792
  }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2793
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2794
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2795
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
  2796
  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
  2797
}
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2798
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2799
// 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
  2800
// bind policy to MPOL_PREFERRED for the current thread.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2801
#define USE_MPOL_PREFERRED 0
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2802
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2803
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
  2804
  // 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
  2805
  // 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
  2806
  // 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
  2807
  // 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
  2808
  // 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
  2809
  // 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
  2810
  // free large pages.
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2811
  Linux::numa_set_bind_policy(USE_MPOL_PREFERRED);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2812
  Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2813
}
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
bool os::numa_topology_changed()   { return false; }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2816
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2817
size_t os::numa_get_groups_num() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2818
  int max_node = Linux::numa_max_node();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2819
  return max_node > 0 ? max_node + 1 : 1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2820
}
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
int os::numa_get_group_id() {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2823
  int cpu_id = Linux::sched_getcpu();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2824
  if (cpu_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2825
    int lgrp_id = Linux::get_node_by_cpu(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2826
    if (lgrp_id != -1) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2827
      return lgrp_id;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2828
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2833
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
  2834
  for (size_t i = 0; i < size; i++) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2835
    ids[i] = i;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2836
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2837
  return size;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2838
}
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2839
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
bool os::get_page_info(char *start, page_info* info) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2848
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2849
int os::Linux::sched_getcpu_syscall(void) {
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2850
  unsigned int cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2851
  int retval = -1;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2852
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2853
#if defined(IA32)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2854
# ifndef SYS_getcpu
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2855
# define SYS_getcpu 318
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2856
# endif
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2857
  retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2858
#elif defined(AMD64)
10496
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2859
// 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
  2860
// to be able to compile on old linuxes.
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2861
# define __NR_vgetcpu 2
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2862
# define VSYSCALL_START (-10UL << 20)
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2863
# define VSYSCALL_SIZE 1024
b209db6147cf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 10494
diff changeset
  2864
# 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
  2865
  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
  2866
  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
  2867
  retval = vgetcpu(&cpu, NULL, NULL);
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2868
#endif
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2869
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2870
  return (retval == -1) ? retval : cpu;
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2871
}
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2872
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2873
// Something to do with the numa-aware allocator needs these symbols
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2874
extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2875
extern "C" JNIEXPORT void numa_error(char *where) { }
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  2876
extern "C" JNIEXPORT int fork1() { return fork(); }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2877
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2878
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2879
// 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
  2880
// 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
  2881
// 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
  2882
// we should use the base version.
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2883
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
  2884
  void *f = dlvsym(handle, name, "libnuma_1.1");
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2885
  if (f == NULL) {
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2886
    f = dlsym(handle, name);
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2887
  }
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2888
  return f;
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2889
}
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2890
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2891
bool os::Linux::libnuma_init() {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2892
  // sched_getcpu() should be in libc.
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2893
  set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2894
                                  dlsym(RTLD_DEFAULT, "sched_getcpu")));
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2895
10239
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2896
  // If it's not, try a direct syscall.
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2897
  if (sched_getcpu() == -1)
c7af330d33d9 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 10238
diff changeset
  2898
    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
  2899
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2900
  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
  2901
    void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2902
    if (handle != NULL) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2903
      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
  2904
                                           libnuma_dlsym(handle, "numa_node_to_cpus")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2905
      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
  2906
                                       libnuma_dlsym(handle, "numa_max_node")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2907
      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
  2908
                                        libnuma_dlsym(handle, "numa_available")));
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2909
      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
  2910
                                            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
  2911
      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
  2912
                                            libnuma_dlsym(handle, "numa_interleave_memory")));
19726
c086d352d3f7 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 18683
diff changeset
  2913
      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
  2914
                                            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
  2915
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2916
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2917
      if (numa_available() != -1) {
2753
1e9bbaae891b 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 2751
diff changeset
  2918
        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
  2919
        // Create a cpu -> node mapping
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2920
        _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
  2921
        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
  2922
        return true;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2923
      }
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
  }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2926
  return false;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2927
}
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
// 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
  2930
// The table is later used in get_node_by_cpu().
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2931
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
  2932
  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
  2933
                              // 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
  2934
                              // 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
  2935
                              // 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
  2936
                              // 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
  2937
                              // 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
  2938
                              // in the library.
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2939
  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
  2940
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  2941
  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
  2942
  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
  2943
  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
  2944
    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
  2945
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2946
  cpu_to_node()->clear();
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2947
  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
  2948
  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
  2949
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2950
  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
  2951
  for (size_t i = 0; i < node_num; i++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2952
    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
  2953
      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
  2954
        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
  2955
          for (size_t k = 0; k < BitsPerCLong; k++) {
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2956
            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
  2957
              cpu_to_node()->at_put(j * BitsPerCLong + k, i);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2958
            }
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
  }
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2964
  FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2965
}
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
int os::Linux::get_node_by_cpu(int cpu_id) {
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2968
  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
  2969
    return cpu_to_node()->at(cpu_id);
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2970
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2971
  return -1;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2972
}
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
GrowableArray<int>* os::Linux::_cpu_to_node;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2975
os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2976
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
  2977
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
  2978
os::Linux::numa_available_func_t os::Linux::_numa_available;
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2979
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
  2980
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
  2981
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
  2982
unsigned long* os::Linux::_numa_all_nodes;
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  2983
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  2984
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
  2985
  uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2986
                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  2987
  return res  != (uintptr_t) MAP_FAILED;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  2990
// 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
  2991
// 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
  2992
// 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
  2993
// 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
  2994
// 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
  2995
// 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
  2996
//
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  2997
// 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
  2998
// 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
  2999
// 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
  3000
// 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
  3001
// 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
  3002
// create_stack_guard_pages() is called.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3003
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3004
// Find the bounds of the stack mapping.  Return true for success.
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3005
//
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3006
// 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
  3007
// 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
  3008
// 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
  3009
// 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
  3010
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3011
static
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3012
bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3013
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3014
  char buf[128];
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3015
  int fd, sz;
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3016
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3017
  if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3018
    return false;
9125
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3019
  }
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3020
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3021
  const char kw[] = "[stack]";
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3022
  const int kwlen = sizeof(kw)-1;
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3023
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3024
  // Address part of /proc/self/maps couldn't be more than 128 bytes
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3025
  while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3026
     if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3027
        // Extract addresses
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3028
        if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3029
           uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3030
           if (sp >= *bottom && sp <= *top) {
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3031
              ::close(fd);
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3032
              return true;
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3033
           }
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3034
        }
9125
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3035
     }
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3036
  }
9125
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3037
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3038
 ::close(fd);
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3039
  return false;
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3040
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3041
9125
3b9a527cd492 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 8476
diff changeset
  3042
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3043
// 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
  3044
// 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
  3045
// 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
  3046
// munmap() the guard pages we don't leave a hole in the stack
6420
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3047
// mapping. This only affects the main/initial thread, but guard
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3048
// against future OS changes
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3049
bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3050
  uintptr_t stack_extent, stack_base;
6420
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3051
  bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3052
  if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3053
      assert(os::Linux::is_initial_thread(),
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3054
           "growable stack in non-initial thread");
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3055
    if (stack_extent < (uintptr_t)addr)
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3056
      ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3057
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3058
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3059
  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
  3060
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3061
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3062
// 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
  3063
// 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
  3064
// affects the main/initial thread, but guard against future OS changes
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3065
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
  3066
  uintptr_t stack_extent, stack_base;
6420
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3067
  bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3068
  if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3069
      assert(os::Linux::is_initial_thread(),
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3070
           "growable stack in non-initial thread");
a4205fed5b18 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 6176
diff changeset
  3071
5085
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3072
    return ::munmap(addr, size) == 0;
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3073
  }
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3074
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3075
  return os::uncommit_memory(addr, size);
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3076
}
4f0c435f8c3c 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 4493
diff changeset
  3077
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
static address _highest_vm_reserved_address = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
// If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
// at 'requested_addr'. If there are existing memory mappings at the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
// location, however, they will be overwritten. If 'fixed' is false,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
// 'requested_addr' is only treated as a hint, the return value may or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
// may not start from the requested address. Unlike Linux mmap(), this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
// function returns NULL to indicate failure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
  char * addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
  int flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
  flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
  if (fixed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
    assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
17083
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3096
  // 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
  3097
  // touch an uncommitted page. Otherwise, the read/write might
14000894ef39 8012015: Use PROT_NONE when reserving memory
mikael
parents: 16672
diff changeset
  3098
  // 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
  3099
  addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
                       flags, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
  if (addr != MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
    // anon_mmap() should only get called during VM initialization,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
    // don't need lock (actually we can skip locking even it can be called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
    // from multiple threads, because _highest_vm_reserved_address is just a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
    // hint about the upper limit of non-stack memory regions.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
    if ((address)addr + bytes > _highest_vm_reserved_address) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
      _highest_vm_reserved_address = (address)addr + bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
  return addr == MAP_FAILED ? NULL : addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
// Don't update _highest_vm_reserved_address, because there might be memory
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
// regions above addr + size. If so, releasing a memory region only creates
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
// a hole in the address space, it doesn't help prevent heap-stack collision.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
static int anon_munmap(char * addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
  return ::munmap(addr, size) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3123
char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
                         size_t alignment_hint) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
  return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3128
bool os::pd_release_memory(char* addr, size_t size) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
  return anon_munmap(addr, size);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
static address highest_vm_reserved_address() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
  return _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
static bool linux_mprotect(char* addr, size_t size, int prot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
  // Linux wants the mprotect address argument to be page aligned.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
  char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
  // According to SUSv3, mprotect() should only be used with mappings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
  // established by mmap(), and mmap() always maps whole pages. Unaligned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
  // 'addr' likely indicates problem in the VM (e.g. trying to change
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
  // protection of malloc'ed or statically allocated memory). Check the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
  // caller if you hit this assert.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
  assert(addr == bottom, "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
  size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
  return ::mprotect(bottom, size, prot) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3151
// Set protections specified
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3152
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
  3153
                        bool is_committed) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3154
  unsigned int p = 0;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3155
  switch (prot) {
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3156
  case MEM_PROT_NONE: p = PROT_NONE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3157
  case MEM_PROT_READ: p = PROT_READ; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3158
  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3159
  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
  3160
  default:
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3161
    ShouldNotReachHere();
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3162
  }
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3163
  // is_committed is unused.
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  3164
  return linux_mprotect(addr, bytes, p);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
bool os::guard_memory(char* addr, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
  return linux_mprotect(addr, size, PROT_NONE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
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
  3172
  return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3175
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
  3176
  bool result = false;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3177
  void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3178
                  MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3179
                  -1, 0);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3180
18069
e6d4971c8650 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 18025
diff changeset
  3181
  if (p != MAP_FAILED) {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3182
    // 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
  3183
    FILE *fp = fopen("/proc/self/maps", "r");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3184
    if (fp) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3185
      while (!feof(fp)) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3186
        char chars[257];
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3187
        long x = 0;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3188
        if (fgets(chars, sizeof(chars), fp)) {
9625
822a93889b58 7043564: compile warning and copyright fixes
iveresov
parents: 9419
diff changeset
  3189
          if (sscanf(chars, "%lx-%*x", &x) == 1
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3190
              && x == (long)p) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3191
            if (strstr (chars, "hugepage")) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3192
              result = true;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3193
              break;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3194
            }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3195
          }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3196
        }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3197
      }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3198
      fclose(fp);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3199
    }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3200
    munmap (p, page_size);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3201
    if (result)
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3202
      return true;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3203
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3204
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3205
  if (warn) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3206
    warning("HugeTLBFS is not supported by the operating system.");
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3207
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3208
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3209
  return result;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3210
}
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3211
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3212
/*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3213
* 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
  3214
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3215
* From the coredump_filter documentation:
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3216
*
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3217
* - (bit 0) anonymous private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3218
* - (bit 1) anonymous shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3219
* - (bit 2) file-backed private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3220
* - (bit 3) file-backed shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3221
* - (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
  3222
*           effective only if the bit 2 is cleared)
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3223
* - (bit 5) hugetlb private memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3224
* - (bit 6) hugetlb shared memory
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3225
*/
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3226
static void set_coredump_filter(void) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3227
  FILE *f;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3228
  long cdm;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3229
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3230
  if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3231
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3232
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3233
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3234
  if (fscanf(f, "%lx", &cdm) != 1) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3235
    fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3236
    return;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3237
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3238
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3239
  rewind(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3240
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3241
  if ((cdm & LARGEPAGES_BIT) == 0) {
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3242
    cdm |= LARGEPAGES_BIT;
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3243
    fprintf(f, "%#lx", cdm);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3244
  }
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3245
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3246
  fclose(f);
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3247
}
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3248
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
// Large page support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
static size_t _large_page_size = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
9419
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3253
void os::large_page_init() {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3254
  if (!UseLargePages) {
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3255
    UseHugeTLBFS = false;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3256
    UseSHM = false;
9419
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3257
    return;
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3258
  }
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3259
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3260
  if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
9419
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3261
    // If UseLargePages is specified on the command line try both methods,
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3262
    // if it's default, then try only HugeTLBFS.
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3263
    if (FLAG_IS_DEFAULT(UseLargePages)) {
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3264
      UseHugeTLBFS = true;
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3265
    } else {
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3266
      UseHugeTLBFS = UseSHM = true;
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  3267
    }
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3268
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
  if (LargePageSizeInBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
    _large_page_size = LargePageSizeInBytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
    // large_page_size on Linux is used to round up heap size. x86 uses either
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
    // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
    // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
    // page as large as 256M.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
    // Here we try to figure out page size by parsing /proc/meminfo and looking
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
    // for a line with the following format:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
    //    Hugepagesize:     2048 kB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
    //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
    // If we can't determine the value (e.g. /proc is not mounted, or the text
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
    // format has been changed), we'll use the largest page size supported by
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
    // the processor.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3286
#ifndef ZERO
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  3287
    _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  3288
                       ARM_ONLY(2 * M) PPC_ONLY(4 * M);
4013
b154310845de 6890308: integrate zero assembler hotspot changes
never
parents: 2753
diff changeset
  3289
#endif // ZERO
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
    FILE *fp = fopen("/proc/meminfo", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
    if (fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
      while (!feof(fp)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
        int x = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
        char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
        if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
          if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
            _large_page_size = x * K;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
            break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
          // skip to next line
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
          for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
            int ch = fgetc(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
            if (ch == EOF || ch == (int)'\n') break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3313
  // print a warning if any large page related flag is specified on command line
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3314
  bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3315
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
  const size_t default_page_size = (size_t)Linux::page_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
  if (_large_page_size > default_page_size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
    _page_sizes[0] = _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
    _page_sizes[1] = default_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
    _page_sizes[2] = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
  }
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3322
  UseHugeTLBFS = UseHugeTLBFS &&
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3323
                 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3324
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3325
  if (UseHugeTLBFS)
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3326
    UseSHM = false;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3327
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3328
  UseLargePages = UseHugeTLBFS || UseSHM;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3329
8119
81eef1b06988 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 8108
diff changeset
  3330
  set_coredump_filter();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
#ifndef SHM_HUGETLB
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
#define SHM_HUGETLB 04000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
2268
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3337
char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3338
  // "exec" is passed in but not used.  Creating the shared image for
bea8be80ec88 6541756: Reduce executable C-heap
coleenp
parents: 2259
diff changeset
  3339
  // 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
  3340
  assert(UseLargePages && UseSHM, "only for SHM large pages");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  key_t key = IPC_PRIVATE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
  char *addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
  bool warn_on_failure = UseLargePages &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
                        (!FLAG_IS_DEFAULT(UseLargePages) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
                         !FLAG_IS_DEFAULT(LargePageSizeInBytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
                        );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  char msg[128];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
  // Create a large shared memory region to attach to based on size.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  // Currently, size is the total size of the heap
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
  int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
  if (shmid == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
     // Possible reasons for shmget failure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
     // 1. shmmax is too small for Java heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
     //    > check shmmax value: cat /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
     //    > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
     // 2. not enough large page memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
     //    > check available large pages: cat /proc/meminfo
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
     //    > increase amount of large pages:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
     //          echo new_value > /proc/sys/vm/nr_hugepages
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
     //      Note 1: different Linux may use different name for this property,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
     //            e.g. on Redhat AS-3 it is "hugetlb_pool".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
     //      Note 2: it's possible there's enough physical memory available but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
     //            they are so fragmented after a long run that they can't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
     //            coalesce into large pages. Try to reserve large pages when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
     //            the system is still "fresh".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
       jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
  // attach to the region
5532
34c4ef11dbed 6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents: 5413
diff changeset
  3377
  addr = (char*)shmat(shmid, req_addr, 0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
  int err = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
  // Remove shmid. If shmat() is successful, the actual shared memory segment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
  // will be deleted when it's detached by shmdt() or when the process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
  // terminates. If shmat() is not successful this will remove the shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
  // segment immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
  shmctl(shmid, IPC_RMID, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
  if ((intptr_t)addr == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
     if (warn_on_failure) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
       jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
       warning(msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
     return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
10494
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  3394
  if ((addr != NULL) && UseNUMAInterleaving) {
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  3395
    numa_make_global(addr, bytes);
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  3396
  }
3f347ed8bd3c 7082969: NUMA interleaving
iveresov
parents: 10239
diff changeset
  3397
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3398
  // The memory is committed
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3399
  MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3400
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  return addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
bool os::release_memory_special(char* base, size_t bytes) {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3405
  MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  // detaching the SHM segment will also delete it, see reserve_memory_special()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
  int rslt = shmdt(base);
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3408
  if (rslt == 0) {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3409
    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
  3410
    return true;
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3411
  } else {
18086
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3412
    tkr.discard();
f44cf213a775 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 18069
diff changeset
  3413
    return false;
15927
f256c20146f4 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 15926
diff changeset
  3414
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
size_t os::large_page_size() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
  return _large_page_size;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3421
// HugeTLBFS allows application to commit large page memory on demand;
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3422
// with SysV SHM the entire memory region must be allocated as shared
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3423
// memory.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
bool os::can_commit_large_page_memory() {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3425
  return UseHugeTLBFS;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3428
bool os::can_execute_large_page_memory() {
9335
7bdd2a3ab3d8 7034464: Support transparent large pages on Linux
iveresov
parents: 8476
diff changeset
  3429
  return UseHugeTLBFS;
252
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3430
}
050143a0dbfb 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 235
diff changeset
  3431
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
// Reserve memory at an arbitrary address, only if that area is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
// available (and not reserved for something else).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  3435
char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  const int max_tries = 10;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
  char* base[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  size_t size[max_tries];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
  const size_t gap = 0x000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
  // Assert only that the size is a multiple of the page size, since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
  // that's all that mmap requires, and since that's all we really know
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  // about at this low abstraction level.  If we need higher alignment,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  // we can either pass an alignment to this method or verify alignment
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
  // in one of the methods further up the call chain.  See bug 5044738.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  // Repeatedly allocate blocks until the block is allocated at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
  // right spot. Give up after max_tries. Note that reserve_memory() will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
  // automatically update _highest_vm_reserved_address if the call is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  // successful. The variable tracks the highest memory address every reserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  // by JVM. It is used to detect heap-stack collision if running with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
  // fixed-stack LinuxThreads. Because here we may attempt to reserve more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  // space than needed, it could confuse the collision detecting code. To
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  // solve the problem, save current _highest_vm_reserved_address and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  // calculate the correct value before return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
  address old_highest = _highest_vm_reserved_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
  // Linux mmap allows caller to pass an address as hint; give it a try first,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
  // if kernel honors the hint then we can return immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
  char * addr = anon_mmap(requested_addr, bytes, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
  if (addr == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
     return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
     // mmap() is successful but it fails to reserve at the requested address
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
     anon_munmap(addr, bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
  for (i = 0; i < max_tries; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
    base[i] = reserve_memory(bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
    if (base[i] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3476
      // Is this the block we wanted?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
      if (base[i] == requested_addr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
        size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
      // Does this overlap the block we wanted? Give back the overlapped
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
      // parts and try again.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
      size_t top_overlap = requested_addr + (bytes + gap) - base[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
      if (top_overlap >= 0 && top_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
        unmap_memory(base[i], top_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
        base[i] += top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
        size[i] = bytes - top_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
        size_t bottom_overlap = base[i] + bytes - requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
        if (bottom_overlap >= 0 && bottom_overlap < bytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
          unmap_memory(requested_addr, bottom_overlap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
          size[i] = bytes - bottom_overlap;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
          size[i] = bytes;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
  // Give back the unused reserved pieces.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
  for (int j = 0; j < i; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
    if (base[j] != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
      unmap_memory(base[j], size[j]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
  if (i < max_tries) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
    _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
    return requested_addr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
    _highest_vm_reserved_address = old_highest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
size_t os::read(int fd, void *buf, unsigned int nBytes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  return ::read(fd, buf, nBytes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
// TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
// Solaris uses poll(), linux uses park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
// Poll() is likely a better choice, assuming that Thread.interrupt()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
// SIGSEGV, see 4355769.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  assert(thread == Thread::current(),  "thread consistency check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  slp->reset() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  OrderAccess::fence() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
  if (interruptible) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
      if (os::is_interrupted(thread, true)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
        return OS_INTRPT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3551
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
      if(millis <= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
        return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
      {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
        assert(thread->is_Java_thread(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
        JavaThread *jt = (JavaThread *) thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
        ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
        OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
        jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
        // cleared by handle_special_suspend_equivalent_condition() or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
        // java_suspend_self() via check_and_wait_while_suspended()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
        slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
        // were we externally suspended while we were waiting?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
        jt->check_and_wait_while_suspended();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
    OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
    jlong prevtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
    for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
      // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
      // the 1st iteration ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
      jlong newtime = javaTimeNanos();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
      if (newtime - prevtime < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
        // time moving backwards, should only happen if no monotonic clock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
        // not a guarantee() because JVM should not abort on kernel/glibc bugs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
        assert(!Linux::supports_monotonic_clock(), "time moving backwards");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
      } else {
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  3590
        millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
      if(millis <= 0) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
      prevtime = newtime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
      slp->park(millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
    return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
int os::naked_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
  // %% make the sleep time an integer flag. for now use 1 millisec.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
  return os::sleep(Thread::current(), 1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
// Sleep forever; naked call to OS-specific sleep; use with CAUTION
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
void os::infinite_sleep() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
  while (true) {    // sleep forever ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
    ::sleep(100);   // ... 100 seconds at a time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
// Used to convert frequent JVM_Yield() to nops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
bool os::dont_yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
  return DontYieldALot;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
void os::yield() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
void os::yield_all(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  // Yields to all threads, including threads with lower priorities
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
  // Threads on Linux are all with same priority. The Solaris style
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
  // os::yield_all() with nanosleep(1ms) is not necessary.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
  sched_yield();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
// Called from the tight loops to possibly influence time-sharing heuristics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
void os::loop_breaker(int attempts) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  os::yield_all(attempts);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
// thread priority support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
// Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
// only supports dynamic priority, static priority must be zero. For real-time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
// applications, Linux supports SCHED_RR which allows static priority (1-99).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
// However, for large multi-threaded applications, SCHED_RR is not only slower
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
// of 5 runs - Sep 2005).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
// The following code actually changes the niceness of kernel-thread/LWP. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
// has an assumption that setpriority() only modifies one kernel-thread/LWP,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
// not the entire user process, and user level threads are 1:1 mapped to kernel
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
// threads. It has always been the case, but could change in the future. For
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
// this reason, the code should not be used as default (ThreadPriorityPolicy=0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
// It is only used when ThreadPriorityPolicy=1 and requires root privilege.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3654
int os::java_to_os_priority[CriticalPriority + 1] = {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
  19,              // 0 Entry should never be used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
   4,              // 1 MinPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
   3,              // 2
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
   2,              // 3
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
   1,              // 4
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
   0,              // 5 NormPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
  -1,              // 6
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  -2,              // 7
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
  -3,              // 8
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
  -4,              // 9 NearMaxPriority
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3669
  -5,              // 10 MaxPriority
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3670
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3671
  -5               // 11 CriticalPriority
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
static int prio_init() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  if (ThreadPriorityPolicy == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
    // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
    // if effective uid is not root. Perhaps, a more elegant way of doing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
    // this is to test CAP_SYS_NICE capability, but that will require libcap.so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
    if (geteuid() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
      if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
        warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
      ThreadPriorityPolicy = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  }
11601
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3686
  if (UseCriticalJavaThreadPriority) {
f359304c1856 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 11483
diff changeset
  3687
    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
  3688
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
OSReturn os::set_native_priority(Thread* thread, int newpri) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
  return (ret == 0) ? OS_OK : OS_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
  if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
    *priority_ptr = java_to_os_priority[NormPriority];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
    return OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
  errno = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
  *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
  return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
// Hint to the underlying OS that a task switch would not be good.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
// Void return because it's a hint and can fail.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
void os::hint_no_preempt() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
// suspend/resume support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
//  the low-level signal-based suspend/resume support is a remnant from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
//  old VM-suspension that used to be for java-suspension, safepoints etc,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
//  within hotspot. Now there is a single use-case for this:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
//    - calling get_thread_pc() on the VMThread by the flat-profiler task
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
//      that runs in the watcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
//  The remaining code is greatly simplified from the more general suspension
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
//  code that used to be used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
//  The protocol is quite simple:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
//  - suspend:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
//      - sends a signal to the target thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
//      - polls the suspend state of the osthread using a yield loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
//      - target thread signal handler (SR_handler) sets suspend state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
//        and blocks in sigsuspend until continued
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
//  - resume:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
//      - sets target osthread state to continue
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
//      - sends signal to end the sigsuspend loop in the SR_handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
//  Note that the SR_lock plays no role in this suspend/resume protocol.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
static void resume_clear_context(OSThread *osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
  osthread->set_ucontext(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
  osthread->set_siginfo(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
  osthread->set_ucontext(context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
  osthread->set_siginfo(siginfo);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
// Handler function invoked when a thread's execution is suspended or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
// resumed. We have to be careful that only async-safe functions are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
// called here (Note: most pthread functions are not async safe and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
// should be avoided.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
// Note: sigwait() is a more natural fit than sigsuspend() from an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
// interface point of view, but sigwait() prevents the signal hander
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
// from being run. libpthread would get very confused by not having
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
// its signal handlers run and prevents sigwait()'s use with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
// mutex granting granting signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
//
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3760
// Currently only ever called on the VMThread and JavaThreads (PC sampling)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
  // Save and restore errno to avoid confusing native code with EINTR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
  // after sigsuspend.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  int old_errno = errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
  OSThread* osthread = thread->osthread();
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3769
  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
  3770
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3771
  os::SuspendResume::State current = osthread->sr.state();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3772
  if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
    suspend_save_context(osthread, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3775
    // 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
  3776
    os::SuspendResume::State state = osthread->sr.suspended();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3777
    if (state == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3778
      sigset_t suspend_set;  // signals for sigsuspend()
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3779
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3780
      // get current set of blocked signals and unblock resume signal
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3781
      pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3782
      sigdelset(&suspend_set, SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3783
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3784
      sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3785
      // wait here until we are resumed
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3786
      while (1) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3787
        sigsuspend(&suspend_set);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3788
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3789
        os::SuspendResume::State result = osthread->sr.running();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3790
        if (result == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3791
          sr_semaphore.signal();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3792
          break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3793
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3794
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3795
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3796
    } else if (state == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3797
      // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3798
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3799
      ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3800
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
    resume_clear_context(osthread);
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3803
  } else if (current == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3804
    // request was cancelled, continue
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3805
  } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3806
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
  } else {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3808
    // ignore
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
  errno = old_errno;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
static int SR_initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3818
  /* Get signal number to use for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
  if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
    int sig = ::strtol(s, 0, 10);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
    if (sig > 0 || sig < _NSIG) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
        SR_signum = sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
  assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
        "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
  sigemptyset(&SR_sigset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
  sigaddset(&SR_sigset, SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
  /* Set up signal handler for suspend/resume */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
  act.sa_flags = SA_RESTART|SA_SIGINFO;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
  act.sa_handler = (void (*)(int)) SR_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
  // SR_signum is blocked by default.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
  // 4528190 - We also need to block pthread restart signal (32 on all
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
  // supported Linux platforms). Note that LinuxThreads need to block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
  // this signal for all threads to work properly. So we don't have
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
  // to use hard-coded signal number when setting up the mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
  pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
  if (sigaction(SR_signum, &act, 0) == -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  // Save signal flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
  os::Linux::set_our_sigflags(SR_signum, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3852
static int sr_notify(OSThread* osthread) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3853
  int status = pthread_kill(osthread->pthread_id(), SR_signum);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3854
  assert_status(status == 0, status, "pthread_kill");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3855
  return status;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3856
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3857
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3858
// "Randomly" selected value for how long we want to spin
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3859
// before bailing out on suspending a thread, also how often
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3860
// we send a signal to a thread we want to resume
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3861
static const int RANDOMLY_LARGE_INTEGER = 1000000;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3862
static const int RANDOMLY_LARGE_INTEGER2 = 100;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3863
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3864
// returns true on success and false on error - really an error is fatal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3865
// but this seems the normal response to library errors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3866
static bool do_suspend(OSThread* osthread) {
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3867
  assert(osthread->sr.is_running(), "thread should be running");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3868
  assert(!sr_semaphore.trywait(), "semaphore has invalid state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3869
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3870
  // mark as suspended and send signal
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3871
  if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3872
    // failed to switch, state wasn't running?
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3873
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3874
    return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3875
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3876
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3877
  if (sr_notify(osthread) != 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3878
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3879
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3880
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3881
  // 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
  3882
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3883
    if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3884
      break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3885
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3886
      // timeout
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3887
      os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3888
      if (cancelled == os::SuspendResume::SR_RUNNING) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3889
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3890
      } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3891
        // 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
  3892
        sr_semaphore.wait();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3893
        break;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3894
      } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3895
        ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3896
        return false;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3897
      }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3898
    }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3899
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3900
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3901
  guarantee(osthread->sr.is_suspended(), "Must be suspended");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3902
  return true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3903
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3905
static void do_resume(OSThread* osthread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3906
  assert(osthread->sr.is_suspended(), "thread should be suspended");
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3907
  assert(!sr_semaphore.trywait(), "invalid semaphore state");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3908
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3909
  if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3910
    // failed to switch to WAKEUP_REQUEST
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3911
    ShouldNotReachHere();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3912
    return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3913
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3914
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3915
  while (true) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3916
    if (sr_notify(osthread) == 0) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3917
      if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3918
        if (osthread->sr.is_running()) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3919
          return;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3920
        }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3921
      }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3922
    } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3923
      ShouldNotReachHere();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3924
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3925
  }
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3926
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  3927
  guarantee(osthread->sr.is_running(), "Must be running!");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3928
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3930
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3931
// interrupt support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3933
void os::interrupt(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3934
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3935
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3936
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3937
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3939
  if (!osthread->interrupted()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3940
    osthread->set_interrupted(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3941
    // More than one thread can get here with the same value of osthread,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3942
    // resulting in multiple notifications.  We do, however, want the store
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3943
    // to interrupted() to be visible to other threads before we execute unpark().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3944
    OrderAccess::fence();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3945
    ParkEvent * const slp = thread->_SleepEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3946
    if (slp != NULL) slp->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3947
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3949
  // For JSR166. Unpark even if interrupt status already was set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3950
  if (thread->is_Java_thread())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3951
    ((JavaThread*)thread)->parker()->unpark();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3952
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3953
  ParkEvent * ev = thread->_ParkEvent ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3954
  if (ev != NULL) ev->unpark() ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3955
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3956
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3957
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3958
bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3959
  assert(Thread::current() == thread || Threads_lock->owned_by_self(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3960
    "possibility of dangling Thread pointer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3962
  OSThread* osthread = thread->osthread();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3963
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3964
  bool interrupted = osthread->interrupted();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3965
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3966
  if (interrupted && clear_interrupted) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3967
    osthread->set_interrupted(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3968
    // consider thread->_SleepEvent->reset() ... optional optimization
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3969
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3970
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3971
  return interrupted;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3972
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3973
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3974
///////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3975
// signal handling (except suspend/resume)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3976
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3977
// This routine may be used by user applications as a "hook" to catch signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3978
// The user-defined signal handler must pass unrecognized signals to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3979
// routine, and if it returns true (non-zero), then the signal handler must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3980
// return immediately.  If the flag "abort_if_unrecognized" is true, then this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3981
// routine will never retun false (zero), but instead will execute a VM panic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3982
// routine kill the process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3983
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3984
// If this routine returns false, it is OK to call it again.  This allows
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3985
// the user-defined signal handler to perform checks either before or after
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3986
// the VM performs its own checks.  Naturally, the user code would be making
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3987
// a serious error if it tried to handle an exception (such as a null check
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3988
// or breakpoint) that the VM was generating for its own correct operation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3989
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3990
// This routine may recognize any of the following kinds of signals:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3991
//    SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3992
// It should be consulted by handlers for any of those signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3993
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3994
// The caller of this routine must pass in the three arguments supplied
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3995
// to the function referred to in the "sa_sigaction" (not the "sa_handler")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3996
// field of the structure passed to sigaction().  This routine assumes that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3997
// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3998
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3999
// Note that the VM will print warnings if it detects conflicting signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4000
// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4001
//
8106
19106a0203fb 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 7901
diff changeset
  4002
extern "C" JNIEXPORT int
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4003
JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4004
                        void* ucontext, int abort_if_unrecognized);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4005
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4006
void signalHandler(int sig, siginfo_t* info, void* uc) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4007
  assert(info != NULL && uc != NULL, "it must be old kernel");
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4008
  int orig_errno = errno;  // Preserve errno value over signal handler.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4009
  JVM_handle_linux_signal(sig, info, uc, true);
15743
f708934a12e7 6749267: Signal handler should save/restore errno
hseigel
parents: 15475
diff changeset
  4010
  errno = orig_errno;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4011
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4013
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4014
// This boolean allows users to forward their own non-matching signals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4015
// to JVM_handle_linux_signal, harmlessly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4016
bool os::Linux::signal_handlers_are_installed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4017
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4018
// For signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4019
struct sigaction os::Linux::sigact[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4020
unsigned int os::Linux::sigs = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4021
bool os::Linux::libjsig_is_loaded = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4022
typedef struct sigaction *(*get_signal_t)(int);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4023
get_signal_t os::Linux::get_signal_action = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4025
struct sigaction* os::Linux::get_chained_signal_action(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4026
  struct sigaction *actp = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4028
  if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4029
    // Retrieve the old signal handler from libjsig
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4030
    actp = (*get_signal_action)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4031
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4032
  if (actp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4033
    // Retrieve the preinstalled signal handler from jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4034
    actp = get_preinstalled_handler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4035
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4036
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4037
  return actp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4038
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4040
static bool call_chained_handler(struct sigaction *actp, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4041
                                 siginfo_t *siginfo, void *context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4042
  // Call the old signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4043
  if (actp->sa_handler == SIG_DFL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4044
    // It's more reasonable to let jvm treat it as an unexpected exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4045
    // instead of taking the default action.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4046
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4047
  } else if (actp->sa_handler != SIG_IGN) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4048
    if ((actp->sa_flags & SA_NODEFER) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4049
      // automaticlly block the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4050
      sigaddset(&(actp->sa_mask), sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4051
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4052
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4053
    sa_handler_t hand;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4054
    sa_sigaction_t sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4055
    bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4056
    // retrieve the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4057
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4058
      sa = actp->sa_sigaction;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4059
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4060
      hand = actp->sa_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4061
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4063
    if ((actp->sa_flags & SA_RESETHAND) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4064
      actp->sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4065
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4066
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4067
    // try to honor the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4068
    sigset_t oset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4069
    pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4070
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4071
    // call into the chained handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4072
    if (siginfo_flag_set) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4073
      (*sa)(sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4074
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4075
      (*hand)(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4076
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4077
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4078
    // restore the signal mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4079
    pthread_sigmask(SIG_SETMASK, &oset, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4080
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4081
  // Tell jvm's signal handler the signal is taken care of.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4082
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4083
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4085
bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4086
  bool chained = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4087
  // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4088
  if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4089
    struct sigaction *actp = get_chained_signal_action(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4090
    if (actp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4091
      chained = call_chained_handler(actp, sig, siginfo, context);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4092
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4093
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4094
  return chained;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4095
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4097
struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4098
  if ((( (unsigned int)1 << sig ) & sigs) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4099
    return &sigact[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4100
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4101
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4102
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4103
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4104
void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4105
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4106
  sigact[sig] = oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4107
  sigs |= (unsigned int)1 << sig;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4108
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4109
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4110
// for diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4111
int os::Linux::sigflags[MAXSIGNUM];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4113
int os::Linux::get_our_sigflags(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4114
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4115
  return sigflags[sig];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4116
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4117
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4118
void os::Linux::set_our_sigflags(int sig, int flags) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4119
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4120
  sigflags[sig] = flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4121
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4122
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4123
void os::Linux::set_signal_handler(int sig, bool set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4124
  // Check for overwrite.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4125
  struct sigaction oldAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4126
  sigaction(sig, (struct sigaction*)NULL, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4128
  void* oldhand = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4129
                ? CAST_FROM_FN_PTR(void*,  oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4130
                : CAST_FROM_FN_PTR(void*,  oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4131
  if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4132
      oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4133
      oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4134
    if (AllowUserSignalHandlers || !set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4135
      // Do not overwrite; user takes responsibility to forward to us.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4136
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4137
    } else if (UseSignalChaining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4138
      // save the old handler in jvm
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4139
      save_preinstalled_handler(sig, oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4140
      // libjsig also interposes the sigaction() call below and saves the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4141
      // old sigaction on it own.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4142
    } else {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4143
      fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4144
                    "%#lx for signal %d.", (long)oldhand, sig));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4145
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4148
  struct sigaction sigAct;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4149
  sigfillset(&(sigAct.sa_mask));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4150
  sigAct.sa_handler = SIG_DFL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4151
  if (!set_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4152
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4153
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4154
    sigAct.sa_sigaction = signalHandler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4155
    sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4156
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4157
  // Save flags, which are set by ours
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4158
  assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4159
  sigflags[sig] = sigAct.sa_flags;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4160
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4161
  int ret = sigaction(sig, &sigAct, &oldAct);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4162
  assert(ret == 0, "check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4163
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4164
  void* oldhand2  = oldAct.sa_sigaction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4165
                  ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4166
                  : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4167
  assert(oldhand2 == oldhand, "no concurrent signal handler installation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4168
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4169
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4170
// install signal handlers for signals that HotSpot needs to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4171
// handle in order to support Java-level exception handling.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4173
void os::Linux::install_signal_handlers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4174
  if (!signal_handlers_are_installed) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4175
    signal_handlers_are_installed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4176
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4177
    // signal-chaining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4178
    typedef void (*signal_setting_t)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4179
    signal_setting_t begin_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4180
    signal_setting_t end_signal_setting = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4181
    begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4182
                             dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4183
    if (begin_signal_setting != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4184
      end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4185
                             dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4186
      get_signal_action = CAST_TO_FN_PTR(get_signal_t,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4187
                            dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4188
      libjsig_is_loaded = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4189
      assert(UseSignalChaining, "should enable signal-chaining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4190
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4191
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4192
      // Tell libjsig jvm is setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4193
      (*begin_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4194
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4196
    set_signal_handler(SIGSEGV, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4197
    set_signal_handler(SIGPIPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4198
    set_signal_handler(SIGBUS, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4199
    set_signal_handler(SIGILL, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4200
    set_signal_handler(SIGFPE, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4201
    set_signal_handler(SIGXFSZ, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4202
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4203
    if (libjsig_is_loaded) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4204
      // Tell libjsig jvm finishes setting signal handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4205
      (*end_signal_setting)();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4206
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4208
    // 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
  4209
    // 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
  4210
    // Log that signal checking is off only if -verbose:jni is specified.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4211
    if (CheckJNICalls) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4212
      if (libjsig_is_loaded) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4213
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4214
          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
  4215
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4216
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4217
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4218
      if (AllowUserSignalHandlers) {
10561
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4219
        if (PrintJNIResolving) {
bf51fe78a9ad 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 10522
diff changeset
  4220
          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
  4221
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4222
        check_signals = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4223
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4225
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4226
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4228
// This is the fastest way to get thread cpu time on Linux.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4229
// Returns cpu time (user+sys) for any thread, not only for current.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4230
// POSIX compliant clocks are implemented in the kernels 2.6.16+.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4231
// It might work on 2.6.10+ with a special kernel/glibc patch.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4232
// For reference, please, see IEEE Std 1003.1-2004:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4233
//   http://www.unix.org/single_unix_specification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4234
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4235
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4236
  struct timespec tp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4237
  int rc = os::Linux::clock_gettime(clockid, &tp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4238
  assert(rc == 0, "clock_gettime is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4239
11251
e29da6b5622b 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 11161
diff changeset
  4240
  return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4241
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4243
/////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4244
// glibc on Linux platform uses non-documented flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4245
// to indicate, that some special sort of signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4246
// trampoline is used.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4247
// We will never set this flag, and we should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4248
// ignore this flag in our diagnostic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4249
#ifdef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4250
#undef SIGNIFICANT_SIGNAL_MASK
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4251
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4252
#define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4254
static const char* get_signal_handler_name(address handler,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4255
                                           char* buf, int buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4256
  int offset;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4257
  bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4258
  if (found) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4259
    // skip directory names
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4260
    const char *p1, *p2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4261
    p1 = buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4262
    size_t len = strlen(os::file_separator());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4263
    while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4264
    jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4265
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4266
    jio_snprintf(buf, buflen, PTR_FORMAT, handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4267
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4268
  return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4269
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4270
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4271
static void print_signal_handler(outputStream* st, int sig,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4272
                                 char* buf, size_t buflen) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4273
  struct sigaction sa;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4275
  sigaction(sig, NULL, &sa);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4277
  // See comment for SIGNIFICANT_SIGNAL_MASK define
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4278
  sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4280
  st->print("%s: ", os::exception_name(sig, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4281
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4282
  address handler = (sa.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4283
    ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4284
    : CAST_FROM_FN_PTR(address, sa.sa_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4285
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4286
  if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4287
    st->print("SIG_DFL");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4288
  } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4289
    st->print("SIG_IGN");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4290
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4291
    st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4292
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4293
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4294
  st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4296
  address rh = VMError::get_resetted_sighandler(sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4297
  // May be, handler was resetted by VMError?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4298
  if(rh != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4299
    handler = rh;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4300
    sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4301
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4302
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4303
  st->print(", sa_flags="   PTR32_FORMAT, sa.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4305
  // Check: is it our handler?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4306
  if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4307
     handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4308
    // It is our signal handler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4309
    // check for flags, reset system-used one!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4310
    if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4311
      st->print(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4312
                ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4313
                os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4314
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4315
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4316
  st->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4317
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4319
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4320
#define DO_SIGNAL_CHECK(sig) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4321
  if (!sigismember(&check_signal_done, sig)) \
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4322
    os::Linux::check_signal_handler(sig)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4324
// This method is a periodic task to check for misbehaving JNI applications
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4325
// under CheckJNI, we can add any periodic checks here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4326
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4327
void os::run_periodic_checks() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4329
  if (check_signals == false) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4330
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4331
  // SEGV and BUS if overridden could potentially prevent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4332
  // generation of hs*.log in the event of a crash, debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4333
  // such a case can be very challenging, so we absolutely
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4334
  // check the following for a good measure:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4335
  DO_SIGNAL_CHECK(SIGSEGV);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4336
  DO_SIGNAL_CHECK(SIGILL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4337
  DO_SIGNAL_CHECK(SIGFPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4338
  DO_SIGNAL_CHECK(SIGBUS);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4339
  DO_SIGNAL_CHECK(SIGPIPE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4340
  DO_SIGNAL_CHECK(SIGXFSZ);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4342
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4343
  // ReduceSignalUsage allows the user to override these handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4344
  // see comments at the very top and jvm_solaris.h
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4345
  if (!ReduceSignalUsage) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4346
    DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4347
    DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4348
    DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4349
    DO_SIGNAL_CHECK(BREAK_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4350
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4352
  DO_SIGNAL_CHECK(SR_signum);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4353
  DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4354
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4356
typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4357
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4358
static os_sigaction_t os_sigaction = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4359
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4360
void os::Linux::check_signal_handler(int sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4361
  char buf[O_BUFLEN];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4362
  address jvmHandler = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4363
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4365
  struct sigaction act;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4366
  if (os_sigaction == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4367
    // only trust the default sigaction, in case it has been interposed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4368
    os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4369
    if (os_sigaction == NULL) return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4370
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4372
  os_sigaction(sig, (struct sigaction*)NULL, &act);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4374
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4375
  act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4377
  address thisHandler = (act.sa_flags & SA_SIGINFO)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4378
    ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4379
    : CAST_FROM_FN_PTR(address, act.sa_handler) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4380
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4382
  switch(sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4383
  case SIGSEGV:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4384
  case SIGBUS:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4385
  case SIGFPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4386
  case SIGPIPE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4387
  case SIGILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4388
  case SIGXFSZ:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4389
    jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4390
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4391
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4392
  case SHUTDOWN1_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4393
  case SHUTDOWN2_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4394
  case SHUTDOWN3_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4395
  case BREAK_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4396
    jvmHandler = (address)user_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4397
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4399
  case INTERRUPT_SIGNAL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4400
    jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4401
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4402
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4403
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4404
    if (sig == SR_signum) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4405
      jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4406
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4407
      return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4408
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4409
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4410
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4411
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4412
  if (thisHandler != jvmHandler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4413
    tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4414
    tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4415
    tty->print_cr("  found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4416
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4417
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4418
  } 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
  4419
    tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4420
    tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4421
    tty->print_cr("  found:" PTR32_FORMAT, act.sa_flags);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4422
    // No need to check this sig any longer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4423
    sigaddset(&check_signal_done, sig);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4424
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4426
  // Dump all the signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4427
  if (sigismember(&check_signal_done, sig)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4428
    print_signal_handlers(tty, buf, O_BUFLEN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4430
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4431
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4432
extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4433
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4434
extern bool signal_name(int signo, char* buf, size_t len);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4436
const char* os::exception_name(int exception_code, char* buf, size_t size) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4437
  if (0 < exception_code && exception_code <= SIGRTMAX) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4438
    // signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4439
    if (!signal_name(exception_code, buf, size)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4440
      jio_snprintf(buf, size, "SIG%d", exception_code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4441
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4442
    return buf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4443
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4444
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4445
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4446
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4448
// this is called _before_ the most of global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4449
void os::init(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4450
  char dummy;   /* used to get a guess on initial stack address */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4451
//  first_hrtime = gethrtime();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4452
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4453
  // With LinuxThreads the JavaMain thread pid (primordial thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4454
  // is different than the pid of the java launcher thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4455
  // So, on Linux, the launcher thread pid is passed to the VM
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4456
  // via the sun.java.launcher.pid property.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4457
  // Use this property instead of getpid() if it was correctly passed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4458
  // See bug 6351349.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4459
  pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4460
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4461
  _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4463
  clock_tics_per_sec = sysconf(_SC_CLK_TCK);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4465
  init_random(1234567);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4466
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4467
  ThreadCritical::initialize();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4468
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4469
  Linux::set_page_size(sysconf(_SC_PAGESIZE));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4470
  if (Linux::page_size() == -1) {
5403
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4471
    fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
6b0dd9c75dde 6888954: argument formatting for assert() and friends
jcoomes
parents: 5237
diff changeset
  4472
                  strerror(errno)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4473
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4474
  init_page_sizes((size_t) Linux::page_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4475
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4476
  Linux::initialize_system_info();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4478
  // main_thread points to the aboriginal thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4479
  Linux::_main_thread = pthread_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4481
  Linux::clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4482
  initial_time_count = os::elapsed_counter();
950
6112b627bb36 6721093: -XX:AppendRatio=N not supported
kamg
parents: 823
diff changeset
  4483
  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
  4484
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4485
  // 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
  4486
  // 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
  4487
  // 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
  4488
  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
  4489
    StackYellowPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4490
    StackRedPages = 1;
98a9d26f1ef1 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 17083
diff changeset
  4491
    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
  4492
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4493
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4494
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4495
// To install functions for atexit system call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4496
extern "C" {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4497
  static void perfMemory_exit_helper() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4498
    perfMemory_exit();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4499
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4500
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4502
// this is called _after_ the global arguments have been parsed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4503
jint os::init_2(void)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4504
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4505
  Linux::fast_thread_clock_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4506
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4507
  // Allocate a single page and mark it as readable for safepoint polling
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4508
  address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4509
  guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4511
  os::set_polling_page( polling_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4512
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4513
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4514
  if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4515
    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4516
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4518
  if (!UseMembar) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4519
    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
  4520
    guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4521
    os::set_memory_serialize_page( mem_serialize_page );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4522
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4523
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4524
    if(Verbose && PrintMiscellaneous)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4525
      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4526
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4527
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4528
9419
f0360dfe734d 7040485: Use transparent huge page on linux by default
iveresov
parents: 9341
diff changeset
  4529
  os::large_page_init();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4530
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4531
  // initialize suspend/resume support - must do this before signal_sets_init()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4532
  if (SR_initialize() != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4533
    perror("SR_initialize failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4534
    return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4535
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4536
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4537
  Linux::signal_sets_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4538
  Linux::install_signal_handlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4539
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4540
  // 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
  4541
  // the java system classes, including StackOverflowError - depends on page
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4542
  // 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
  4543
  // 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
  4544
  // class initialization depending on 32 or 64 bit VM.
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4545
  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
  4546
            (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
  4547
                    (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
  4548
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4549
  size_t threadStackSizeInBytes = ThreadStackSize * K;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4550
  if (threadStackSizeInBytes != 0 &&
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4551
      threadStackSizeInBytes < os::Linux::min_stack_allowed) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4552
        tty->print_cr("\nThe stack size specified is too small, "
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4553
                      "Specify at least %dk",
6964
6e45ffa3bccf 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 6962
diff changeset
  4554
                      os::Linux::min_stack_allowed/ K);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4555
        return JNI_ERR;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4556
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4558
  // Make the stack size a multiple of the page size so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4559
  // the yellow/red zones can be guarded.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4560
  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4561
        vm_page_size()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4562
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4563
  Linux::capture_initial_stack(JavaThread::stack_size_at_create());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4565
  Linux::libpthread_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4566
  if (PrintMiscellaneous && (Verbose || WizardMode)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4567
     tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4568
          Linux::glibc_version(), Linux::libpthread_version(),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4569
          Linux::is_floating_stack() ? "floating stack" : "fixed stack");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4570
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4571
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4572
  if (UseNUMA) {
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4573
    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
  4574
      UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4575
    } else {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4576
      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
  4577
        // 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
  4578
        UseNUMA = false;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4579
      }
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4580
    }
9341
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4581
    // With SHM large pages we cannot uncommit a page, so there's not way
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4582
    // we can make the adaptive lgrp chunk resizing work. If the user specified
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4583
    // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4584
    // disable adaptive resizing.
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4585
    if (UseNUMA && UseLargePages && UseSHM) {
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4586
      if (!FLAG_IS_DEFAULT(UseNUMA)) {
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4587
        if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4588
          UseLargePages = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4589
        } else {
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4590
          warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4591
          UseAdaptiveSizePolicy = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4592
          UseAdaptiveNUMAChunkSizing = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4593
        }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4594
      } else {
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4595
        UseNUMA = false;
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4596
      }
347fa5cdbd39 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 9339
diff changeset
  4597
    }
1615
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4598
    if (!UseNUMA && ForceNUMA) {
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4599
      UseNUMA = true;
b46d9f19bde2 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 1388
diff changeset
  4600
    }
388
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4601
  }
bcc631c5bbec 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 252
diff changeset
  4602
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4603
  if (MaxFDLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4604
    // set the number of file descriptors to max. print out error
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4605
    // if getrlimit/setrlimit fails but continue regardless.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4606
    struct rlimit nbr_files;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4607
    int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4608
    if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4609
      if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4610
        perror("os::init_2 getrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4611
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4612
      nbr_files.rlim_cur = nbr_files.rlim_max;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4613
      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4614
      if (status != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4615
        if (PrintMiscellaneous && (Verbose || WizardMode))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4616
          perror("os::init_2 setrlimit failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4617
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4618
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4619
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4620
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4621
  // Initialize lock used to serialize thread creation (see os::create_thread)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4622
  Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4623
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4624
  // at-exit methods are called in the reverse order of their registration.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4625
  // atexit functions are called on return from main or as a result of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4626
  // call to exit(3C). There can be only 32 of these functions registered
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4627
  // and atexit() does not set errno.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4628
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4629
  if (PerfAllowAtExitRegistration) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4630
    // only register atexit functions if PerfAllowAtExitRegistration is set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4631
    // atexit functions can be delayed until process exit time, which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4632
    // can be problematic for embedded VM situations. Embedded VMs should
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4633
    // call DestroyJavaVM() to assure that VM resources are released.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4635
    // note: perfMemory_exit_helper atexit function may be removed in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4636
    // the future if the appropriate cleanup code can be added to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4637
    // VM_Exit VMOperation's doit method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4638
    if (atexit(perfMemory_exit_helper) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4639
      warning("os::init2 atexit(perfMemory_exit_helper) failed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4640
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4641
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4643
  // initialize thread priority policy
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4644
  prio_init();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4645
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4646
  return JNI_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4647
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4648
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4649
// 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
  4650
void os::init_3(void)
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4651
{
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4652
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4653
  // Start the MemNotifyThread
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4654
  if (LowMemoryProtection) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4655
    MemNotifyThread::start();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4656
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4657
  return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4658
#endif
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  4659
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4660
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4661
// Mark the polling page as unreadable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4662
void os::make_polling_page_unreadable(void) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4663
  if( !guard_memory((char*)_polling_page, Linux::page_size()) )
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4664
    fatal("Could not disable polling page");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4665
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4666
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4667
// Mark the polling page as readable
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4668
void os::make_polling_page_readable(void) {
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4669
  if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4670
    fatal("Could not enable polling page");
823
9a5271881bc0 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 781
diff changeset
  4671
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4672
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4674
int os::active_processor_count() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4675
  // Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4676
  // so just return the number of online processors.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4677
  int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4678
  assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4679
  return online_cpus;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4680
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4681
10739
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4682
void os::set_native_thread_name(const char *name) {
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4683
  // Not yet implemented.
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4684
  return;
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4685
}
91935236600e 7098194: integrate macosx-port changes
dcubed
parents: 10571
diff changeset
  4686
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4687
bool os::distribute_processes(uint length, uint* distribution) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4688
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4689
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4690
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4691
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4692
bool os::bind_to_processor(uint processor_id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4693
  // Not yet implemented.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4694
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4695
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4697
///
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4698
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4699
void os::SuspendedThreadTask::internal_do_task() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4700
  if (do_suspend(_thread->osthread())) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4701
    SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4702
    do_task(context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4703
    do_resume(_thread->osthread());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4704
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4705
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4706
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4707
class PcFetcher : public os::SuspendedThreadTask {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4708
public:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4709
  PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4710
  ExtendedPC result();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4711
protected:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4712
  void do_task(const os::SuspendedThreadTaskContext& context);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4713
private:
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4714
  ExtendedPC _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4715
};
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4716
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4717
ExtendedPC PcFetcher::result() {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4718
  guarantee(is_done(), "task is not done yet.");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4719
  return _epc;
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4720
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4721
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4722
void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4723
  Thread* thread = context.thread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4724
  OSThread* osthread = thread->osthread();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4725
  if (osthread->ucontext() != NULL) {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4726
    _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4727
  } else {
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4728
    // NULL context is unexpected, double-check this is the VMThread
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4729
    guarantee(thread->is_VM_thread(), "can only be called for VMThread");
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4730
  }
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4731
}
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4732
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4733
// Suspends the target using the signal mechanism and then grabs the PC before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4734
// resuming the target. Used by the flat-profiler only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4735
ExtendedPC os::get_thread_pc(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4736
  // Make sure that it is called by the watcher for the VMThread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4737
  assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4738
  assert(thread->is_VM_thread(), "Can only be called for VMThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4739
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4740
  PcFetcher fetcher(thread);
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4741
  fetcher.run();
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  4742
  return fetcher.result();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4743
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4745
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
  4746
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4747
   if (is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4748
      return pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4749
   } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4750
      // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4751
      // word back to default 64bit precision if condvar is signaled. Java
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4752
      // wants 53bit precision.  Save and restore current value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4753
      int fpu = get_fpu_control_word();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4754
      int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4755
      set_fpu_control_word(fpu);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4756
      return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4757
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4758
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4760
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4761
// debug support
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4762
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4763
bool os::find(address addr, outputStream* st) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4764
  Dl_info dlinfo;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4765
  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
  4766
  if (dladdr(addr, &dlinfo) != 0) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4767
    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
  4768
    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4769
      st->print("%s+%#x", dlinfo.dli_sname,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4770
                 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
  4771
    } else if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4772
      st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4773
    } else {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4774
      st->print("<absolute address>");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4775
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  4776
    if (dlinfo.dli_fname != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4777
      st->print(" in %s", dlinfo.dli_fname);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4778
    }
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  4779
    if (dlinfo.dli_fbase != NULL) {
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4780
      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4781
    }
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4782
    st->cr();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4784
    if (Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4785
      // decode some bytes around the PC
16670
4af09aff4237 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 16669
diff changeset
  4786
      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
  4787
      address end   = clamp_address_in_page(addr+40, addr, os::vm_page_size());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4788
      address       lowest = (address) dlinfo.dli_sname;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4789
      if (!lowest)  lowest = (address) dlinfo.dli_fbase;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4790
      if (begin < lowest)  begin = lowest;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4791
      Dl_info dlinfo2;
18683
a6418e038255 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 18086
diff changeset
  4792
      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4793
          && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4794
        end = (address) dlinfo2.dli_saddr;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  4795
      Disassembler::decode(begin, end, st);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4796
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4797
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4798
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4799
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4800
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4801
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4802
////////////////////////////////////////////////////////////////////////////////
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4803
// misc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4805
// This does not do anything on Linux. This is basically a hook for being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4806
// able to use structured exception handling (thread-local exception filters)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4807
// on, e.g., Win32.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4808
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4809
os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4810
                         JavaCallArguments* args, Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4811
  f(value, method, args, thread);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4814
void os::print_statistics() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4815
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4816
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4817
int os::message_box(const char* title, const char* message) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4818
  int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4819
  fdStream err(defaultStream::error_fd());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4820
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4821
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4822
  err.print_raw_cr(title);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4823
  for (i = 0; i < 78; i++) err.print_raw("-");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4824
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4825
  err.print_raw_cr(message);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4826
  for (i = 0; i < 78; i++) err.print_raw("=");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4827
  err.cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4828
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4829
  char buf[16];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4830
  // Prevent process from exiting upon "read error" without consuming all CPU
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4831
  while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4833
  return buf[0] == 'y' || buf[0] == 'Y';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4834
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4835
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4836
int os::stat(const char *path, struct stat *sbuf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4837
  char pathbuf[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4838
  if (strlen(path) > MAX_PATH - 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4839
    errno = ENAMETOOLONG;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4840
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4841
  }
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4842
  os::native_path(strcpy(pathbuf, path));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4843
  return ::stat(pathbuf, sbuf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4844
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4845
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4846
bool os::check_heap(bool force) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4847
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4848
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4850
int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4851
  return ::vsnprintf(buf, count, format, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4852
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4853
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4854
// Is a (classpath) directory empty?
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4855
bool os::dir_is_empty(const char* path) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4856
  DIR *dir = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4857
  struct dirent *ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4858
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4859
  dir = opendir(path);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4860
  if (dir == NULL) return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4862
  /* Scan the directory */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4863
  bool result = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4864
  char buf[sizeof(struct dirent) + MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4865
  while (result && (ptr = ::readdir(dir)) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4866
    if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4867
      result = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4868
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4869
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4870
  closedir(dir);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4871
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4872
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4873
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4874
// 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
  4875
// from src/solaris/hpi/src/system_md.c
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4876
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4877
#ifndef O_DELETE
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4878
#define O_DELETE 0x10000
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4879
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4880
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4881
// 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
  4882
// 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
  4883
// 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
  4884
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4885
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
  4886
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4887
  if (strlen(path) > MAX_PATH - 1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4888
    errno = ENAMETOOLONG;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4889
    return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4890
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4891
  int fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4892
  int o_delete = (oflag & O_DELETE);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4893
  oflag = oflag & ~O_DELETE;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4894
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4895
  fd = ::open64(path, oflag, mode);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4896
  if (fd == -1) return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4897
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4898
  //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
  4899
  {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4900
    struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4901
    int ret = ::fstat64(fd, &buf64);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4902
    int st_mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4903
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4904
    if (ret != -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4905
      if ((st_mode & S_IFMT) == S_IFDIR) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4906
        errno = EISDIR;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4907
        ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4908
        return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4909
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4910
    } else {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4911
      ::close(fd);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4912
      return -1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4913
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4914
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4915
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4916
    /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4917
     * 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
  4918
     * specifically destined for a subprocess should have the
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4919
     * 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
  4920
     * 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
  4921
     * 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
  4922
     * UNIXProcess.c), and this in turn might:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4923
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4924
     * - 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
  4925
     *   descriptors, resulting in mysterious hangs, or
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4926
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4927
     * - 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
  4928
     *   suffering from bug 1085341.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4929
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4930
     * (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
  4931
     * design flaw)
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4932
     *
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4933
     * See:
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4934
     * 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
  4935
     * 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
  4936
     * 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
  4937
     */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4938
#ifdef FD_CLOEXEC
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4939
    {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4940
        int flags = ::fcntl(fd, F_GETFD);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4941
        if (flags != -1)
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4942
            ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4943
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4944
#endif
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4945
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4946
  if (o_delete != 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4947
    ::unlink(path);
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4948
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4949
  return fd;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4950
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4951
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4952
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4953
// create binary file, rewriting existing file if required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4954
int os::create_binary_file(const char* path, bool rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4955
  int oflags = O_WRONLY | O_CREAT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4956
  if (!rewrite_existing) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4957
    oflags |= O_EXCL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4958
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4959
  return ::open64(path, oflags, S_IREAD | S_IWRITE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4960
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4962
// return current position of file pointer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4963
jlong os::current_file_offset(int fd) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4964
  return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4965
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4966
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4967
// move file pointer to the specified offset
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4968
jlong os::seek_to_file_offset(int fd, jlong offset) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4969
  return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4970
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  4971
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4972
// This code originates from JDK's sysAvailable
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4973
// 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
  4974
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4975
int os::available(int fd, jlong *bytes) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4976
  jlong cur, end;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4977
  int mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4978
  struct stat64 buf64;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4979
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4980
  if (::fstat64(fd, &buf64) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4981
    mode = buf64.st_mode;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4982
    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
  4983
      /*
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4984
      * 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
  4985
      * 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
  4986
      * blocking, interruptible calls in this file.
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4987
      */
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4988
      int n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4989
      if (::ioctl(fd, FIONREAD, &n) >= 0) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4990
        *bytes = n;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4991
        return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4992
      }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4993
    }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4994
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4995
  if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4996
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4997
  } 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
  4998
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  4999
  } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5000
    return 0;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5001
  }
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5002
  *bytes = end - cur;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5003
  return 1;
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5004
}
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5005
7458
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5006
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
  5007
  // 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
  5008
  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
  5009
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5010
  //%% 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
  5011
  // 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
  5012
  return (ret < 0) ? 0 : 1;
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5013
}
3f956542f1fd 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 7448
diff changeset
  5014
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5015
// Map a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5016
char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5017
                     char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5018
                     bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5019
  int prot;
11967
ce179af268b1 7142641: -Xshared:on fails on ARM
dlong
parents: 11601
diff changeset
  5020
  int flags = MAP_PRIVATE;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5022
  if (read_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5023
    prot = PROT_READ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5024
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5025
    prot = PROT_READ | PROT_WRITE;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5026
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5028
  if (allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5029
    prot |= PROT_EXEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5030
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5031
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5032
  if (addr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5033
    flags |= MAP_FIXED;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5034
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5035
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5036
  char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5037
                                     fd, file_offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5038
  if (mapped_address == MAP_FAILED) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5039
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5040
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5041
  return mapped_address;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5042
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5045
// Remap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5046
char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5047
                       char *addr, size_t bytes, bool read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5048
                       bool allow_exec) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5049
  // same as map_memory() on this OS
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5050
  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5051
                        allow_exec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5052
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5055
// Unmap a block of memory.
13195
be27e1b6a4b9 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 12735
diff changeset
  5056
bool os::pd_unmap_memory(char* addr, size_t bytes) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5057
  return munmap(addr, bytes) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5058
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5059
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5060
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5061
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5062
static clockid_t thread_cpu_clockid(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5063
  pthread_t tid = thread->osthread()->pthread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5064
  clockid_t clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5066
  // Get thread clockid
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5067
  int rc = os::Linux::pthread_getcpuclockid(tid, &clockid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5068
  assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5069
  return clockid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5070
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5072
// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5073
// are used by JVM M&M and JVMTI to get user+sys or user CPU time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5074
// of a thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5075
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5076
// current_thread_cpu_time() and thread_cpu_time(Thread*) returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5077
// the fast estimate available on the platform.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5078
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5079
jlong os::current_thread_cpu_time() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5080
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5081
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5082
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5083
    // return user + sys since the cost is the same
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5084
    return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5085
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5086
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5088
jlong os::thread_cpu_time(Thread* thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5089
  // consistent with what current_thread_cpu_time() returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5090
  if (os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5091
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5092
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5093
    return slow_thread_cpu_time(thread, true /* user + sys */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5094
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5095
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5097
jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5098
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5099
    return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5100
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5101
    return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5102
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5103
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5105
jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5106
  if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5107
    return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5108
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5109
    return slow_thread_cpu_time(thread, user_sys_cpu_time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5111
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5113
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5114
//  -1 on error.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5115
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5116
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5117
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5118
  static bool proc_task_unchecked = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5119
  static const char *proc_stat_path = "/proc/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5120
  pid_t  tid = thread->osthread()->thread_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5121
  char *s;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5122
  char stat[2048];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5123
  int statlen;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5124
  char proc_name[64];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5125
  int count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5126
  long sys_time, user_time;
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5127
  char cdummy;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5128
  int idummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5129
  long ldummy;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5130
  FILE *fp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5131
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5132
  // The /proc/<tid>/stat aggregates per-process usage on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5133
  // new Linux kernels 2.6+ where NPTL is supported.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5134
  // The /proc/self/task/<tid>/stat still has the per-thread usage.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5135
  // 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
  5136
  // 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
  5137
  // /proc/self/task, so we check its availability.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5138
  if (proc_task_unchecked && os::Linux::is_NPTL()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5139
    // This is executed only once
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5140
    proc_task_unchecked = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5141
    fp = fopen("/proc/self/task", "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5142
    if (fp != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5143
      proc_stat_path = "/proc/self/task/%d/stat";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5144
      fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5145
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5146
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5147
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5148
  sprintf(proc_name, proc_stat_path, tid);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5149
  fp = fopen(proc_name, "r");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5150
  if ( fp == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5151
  statlen = fread(stat, 1, 2047, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5152
  stat[statlen] = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5153
  fclose(fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5155
  // Skip pid and the command string. Note that we could be dealing with
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5156
  // weird command names, e.g. user could decide to rename java launcher
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5157
  // to "java 1.4.2 :)", then the stat file would look like
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5158
  //                1234 (java 1.4.2 :)) R ... ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5159
  // We don't really need to know the command string, just find the last
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5160
  // occurrence of ")" and then start parsing from there. See bug 4726580.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5161
  s = strrchr(stat, ')');
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5162
  if (s == NULL ) return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5163
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5164
  // Skip blank chars
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5165
  do s++; while (isspace(*s));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5166
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5167
  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
  5168
                 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5169
                 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5170
                 &user_time, &sys_time);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5171
  if ( count != 13 ) return -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5172
  if (user_sys_cpu_time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5173
    return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5174
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5175
    return (jlong)user_time * (1000000000 / clock_tics_per_sec);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5176
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5177
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5178
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5179
void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5180
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5181
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5182
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5183
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5184
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5185
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5186
void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5187
  info_ptr->max_value = ALL_64_BITS;       // will not wrap in less than 64 bits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5188
  info_ptr->may_skip_backward = false;     // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5189
  info_ptr->may_skip_forward = false;      // elapsed time not wall time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5190
  info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;  // user+system time is returned
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5191
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5193
bool os::is_thread_cpu_time_supported() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5194
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5195
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5196
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5197
// System loadavg support.  Returns -1 if load average cannot be obtained.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5198
// Linux doesn't yet have a (official) notion of processor sets,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5199
// so just return the system wide load average.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5200
int os::loadavg(double loadavg[], int nelem) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5201
  return ::getloadavg(loadavg, nelem);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5202
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5203
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5204
void os::pause() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5205
  char filename[MAX_PATH];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5206
  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5207
    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5208
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5209
    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5210
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5212
  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5213
  if (fd != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5214
    struct stat buf;
7405
e6fc8d3926f8 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 7397
diff changeset
  5215
    ::close(fd);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5216
    while (::stat(filename, &buf) == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5217
      (void)::poll(NULL, 0, 100);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5218
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5219
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5220
    jio_fprintf(stderr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5221
      "Could not open pause file '%s', continuing immediately.\n", filename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5222
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5223
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5224
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5225
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5226
// Refer to the comments in os_solaris.cpp park-unpark.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5227
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5228
// Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5229
// hang indefinitely.  For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5230
// For specifics regarding the bug see GLIBC BUGID 261237 :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5231
//    http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5232
// Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5233
// will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5234
// is used.  (The simple C test-case provided in the GLIBC bug report manifests the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5235
// hang).  The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5236
// and monitorenter when we're using 1-0 locking.  All those operations may result in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5237
// calls to pthread_cond_timedwait().  Using LD_ASSUME_KERNEL to use an older version
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5238
// of libpthread avoids the problem, but isn't practical.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5239
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5240
// Possible remedies:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5241
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5242
// 1.   Establish a minimum relative wait time.  50 to 100 msecs seems to work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5243
//      This is palliative and probabilistic, however.  If the thread is preempted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5244
//      between the call to compute_abstime() and pthread_cond_timedwait(), more
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5245
//      than the minimum period may have passed, and the abstime may be stale (in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5246
//      past) resultin in a hang.   Using this technique reduces the odds of a hang
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5247
//      but the JVM is still vulnerable, particularly on heavily loaded systems.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5248
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5249
// 2.   Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5250
//      of the usual flag-condvar-mutex idiom.  The write side of the pipe is set
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5251
//      NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5252
//      reduces to poll()+read().  This works well, but consumes 2 FDs per extant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5253
//      thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5254
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5255
// 3.   Embargo pthread_cond_timedwait() and implement a native "chron" thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5256
//      that manages timeouts.  We'd emulate pthread_cond_timedwait() by enqueuing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5257
//      a timeout request to the chron thread and then blocking via pthread_cond_wait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5258
//      This also works well.  In fact it avoids kernel-level scalability impediments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5259
//      on certain platforms that don't handle lots of active pthread_cond_timedwait()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5260
//      timers in a graceful fashion.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5261
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5262
// 4.   When the abstime value is in the past it appears that control returns
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5263
//      correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5264
//      Subsequent timedwait/wait calls may hang indefinitely.  Given that, we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5265
//      can avoid the problem by reinitializing the condvar -- by cond_destroy()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5266
//      followed by cond_init() -- after all calls to pthread_cond_timedwait().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5267
//      It may be possible to avoid reinitialization by checking the return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5268
//      value from pthread_cond_timedwait().  In addition to reinitializing the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5269
//      condvar we must establish the invariant that cond_signal() is only called
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5270
//      within critical sections protected by the adjunct mutex.  This prevents
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5271
//      cond_signal() from "seeing" a condvar that's in the midst of being
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5272
//      reinitialized or that is corrupt.  Sadly, this invariant obviates the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5273
//      desirable signal-after-unlock optimization that avoids futile context switching.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5274
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5275
//      I'm also concerned that some versions of NTPL might allocate an auxilliary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5276
//      structure when a condvar is used or initialized.  cond_destroy()  would
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5277
//      release the helper structure.  Our reinitialize-after-timedwait fix
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5278
//      put excessive stress on malloc/free and locks protecting the c-heap.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5279
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5280
// We currently use (4).  See the WorkAroundNTPLTimedWaitHang flag.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5281
// It may be possible to refine (4) by checking the kernel and NTPL verisons
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5282
// and only enabling the work-around for vulnerable environments.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5284
// utility to compute the abstime argument to timedwait:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5285
// millis is the relative timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5286
// abstime will be the absolute timeout time
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5287
// TODO: replace compute_abstime() with unpackTime()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5288
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5289
static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5290
  if (millis < 0)  millis = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5291
  struct timeval now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5292
  int status = gettimeofday(&now, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5293
  assert(status == 0, "gettimeofday");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5294
  jlong seconds = millis / 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5295
  millis %= 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5296
  if (seconds > 50000000) { // see man cond_timedwait(3T)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5297
    seconds = 50000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5298
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5299
  abstime->tv_sec = now.tv_sec  + seconds;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5300
  long       usec = now.tv_usec + millis * 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5301
  if (usec >= 1000000) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5302
    abstime->tv_sec += 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5303
    usec -= 1000000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5304
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5305
  abstime->tv_nsec = usec * 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5306
  return abstime;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5307
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5309
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5310
// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5311
// Conceptually TryPark() should be equivalent to park(0).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5312
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5313
int os::PlatformEvent::TryPark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5314
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5315
    const int v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5316
    guarantee ((v == 0) || (v == 1), "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5317
    if (Atomic::cmpxchg (0, &_Event, v) == v) return v  ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5318
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5319
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5321
void os::PlatformEvent::park() {       // AKA "down()"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5322
  // Invariant: Only the thread associated with the Event/PlatformEvent
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5323
  // may call park().
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5324
  // TODO: assert that _Assoc != NULL or _Assoc == Self
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5325
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5326
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5327
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5328
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5329
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5330
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5331
  if (v == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5332
     // Do this the hard way by blocking ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5333
     int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5334
     assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5335
     guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5336
     ++ _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5337
     while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5338
        status = pthread_cond_wait(_cond, _mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5339
        // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5340
        // Treat this the same as if the wait was interrupted
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5341
        if (status == ETIME) { status = EINTR; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5342
        assert_status(status == 0 || status == EINTR, status, "cond_wait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5343
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5344
     -- _nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5345
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5346
    _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5347
     status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5348
     assert_status(status == 0, status, "mutex_unlock");
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5349
    // 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
  5350
    // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5351
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5352
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5353
  guarantee (_Event >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5354
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5356
int os::PlatformEvent::park(jlong millis) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5357
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5358
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5359
  int v ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5360
  for (;;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5361
      v = _Event ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5362
      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5363
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5364
  guarantee (v >= 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5365
  if (v != 0) return OS_OK ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5366
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5367
  // We do this the hard way, by blocking the thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5368
  // Consider enforcing a minimum timeout value.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5369
  struct timespec abst;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5370
  compute_abstime(&abst, millis);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5371
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5372
  int ret = OS_TIMEOUT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5373
  int status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5374
  assert_status(status == 0, status, "mutex_lock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5375
  guarantee (_nParked == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5376
  ++_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5377
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5378
  // Object.wait(timo) will return because of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5379
  // (a) notification
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5380
  // (b) timeout
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5381
  // (c) thread.interrupt
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5382
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5383
  // Thread.interrupt and object.notify{All} both call Event::set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5384
  // That is, we treat thread.interrupt as a special case of notification.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5385
  // The underlying Solaris implementation, cond_timedwait, admits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5386
  // spurious/premature wakeups, but the JLS/JVM spec prevents the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5387
  // JVM from making those visible to Java code.  As such, we must
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5388
  // filter out spurious wakeups.  We assume all ETIME returns are valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5389
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5390
  // TODO: properly differentiate simultaneous notify+interrupt.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5391
  // In that case, we should propagate the notify to another waiter.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5392
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5393
  while (_Event < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5394
    status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5395
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5396
      pthread_cond_destroy (_cond);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5397
      pthread_cond_init (_cond, NULL) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5398
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5399
    assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5400
                  status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5401
                  status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5402
    if (!FilterSpuriousWakeups) break ;                 // previous semantics
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5403
    if (status == ETIME || status == ETIMEDOUT) break ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5404
    // We consume and ignore EINTR and spurious wakeups.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5406
  --_nParked ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5407
  if (_Event >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5408
     ret = OS_OK;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5409
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5410
  _Event = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5411
  status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5412
  assert_status(status == 0, status, "mutex_unlock");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5413
  assert (_nParked == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5414
  // 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
  5415
  // correctly with each other.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5416
  OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5417
  return ret;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5418
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5419
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5420
void os::PlatformEvent::unpark() {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5421
  // Transitions for _Event:
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5422
  //    0 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5423
  //    1 :=> 1
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5424
  //   -1 :=> either 0 or 1; must signal target thread
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5425
  //          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
  5426
  //          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
  5427
  //          unpark() calls.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5428
  // See also: "Semaphores in Plan 9" by Mullender & Cox
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5429
  //
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5430
  // 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
  5431
  // 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
  5432
  // 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
  5433
  // 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
  5434
  // 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
  5435
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5436
  if (Atomic::xchg(1, &_Event) >= 0) return;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5437
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5438
  // 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
  5439
  int status = pthread_mutex_lock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5440
  assert_status(status == 0, status, "mutex_lock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5441
  int AnyWaiters = _nParked;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5442
  assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5443
  if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5444
    AnyWaiters = 0;
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5445
    pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5446
  }
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5447
  status = pthread_mutex_unlock(_mutex);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5448
  assert_status(status == 0, status, "mutex_unlock");
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5449
  if (AnyWaiters != 0) {
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5450
    status = pthread_cond_signal(_cond);
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5451
    assert_status(status == 0, status, "cond_signal");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5452
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5454
  // Note that we signal() _after dropping the lock for "immortal" Events.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5455
  // This is safe and avoids a common class of  futile wakeups.  In rare
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5456
  // circumstances this can cause a thread to return prematurely from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5457
  // cond_{timed}wait() but the spurious wakeup is benign and the victim will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5458
  // simply re-test the condition and re-park itself.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5459
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5460
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5461
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5462
// JSR166
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5463
// -------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5464
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5465
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5466
 * The solaris and linux implementations of park/unpark are fairly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5467
 * conservative for now, but can be improved. They currently use a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5468
 * mutex/condvar pair, plus a a count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5469
 * Park decrements count if > 0, else does a condvar wait.  Unpark
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5470
 * sets count to 1 and signals condvar.  Only one thread ever waits
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5471
 * on the condvar. Contention seen when trying to park implies that someone
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5472
 * is unparking you, so don't wait. And spurious returns are fine, so there
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5473
 * is no need to track notifications.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5474
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5475
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5476
#define MAX_SECS 100000000
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5477
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5478
 * This code is common to linux and solaris and will be moved to a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5479
 * common place in dolphin.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5480
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5481
 * The passed in time value is either a relative time in nanoseconds
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5482
 * or an absolute time in milliseconds. Either way it has to be unpacked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5483
 * into suitable seconds and nanoseconds components and stored in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5484
 * given timespec structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5485
 * Given time is a 64-bit value and the time_t used in the timespec is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5486
 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5487
 * overflow if times way in the future are given. Further on Solaris versions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5488
 * prior to 10 there is a restriction (see cond_timedwait) that the specified
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5489
 * number of seconds, in abstime, is less than current_time  + 100,000,000.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5490
 * As it will be 28 years before "now + 100000000" will overflow we can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5491
 * ignore overflow and just impose a hard-limit on seconds using the value
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5492
 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5493
 * years from "now".
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5494
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5495
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5496
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5497
  assert (time > 0, "convertTime");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5498
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5499
  struct timeval now;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5500
  int status = gettimeofday(&now, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5501
  assert(status == 0, "gettimeofday");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5502
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5503
  time_t max_secs = now.tv_sec + MAX_SECS;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5505
  if (isAbsolute) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5506
    jlong secs = time / 1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5507
    if (secs > max_secs) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5508
      absTime->tv_sec = max_secs;
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
      absTime->tv_sec = secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5512
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5513
    absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5514
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5515
  else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5516
    jlong secs = time / NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5517
    if (secs >= MAX_SECS) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5518
      absTime->tv_sec = max_secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5519
      absTime->tv_nsec = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5520
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5521
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5522
      absTime->tv_sec = now.tv_sec + secs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5523
      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5524
      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5525
        absTime->tv_nsec -= NANOSECS_PER_SEC;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5526
        ++absTime->tv_sec; // note: this must be <= max_secs
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5527
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5528
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5529
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5530
  assert(absTime->tv_sec >= 0, "tv_sec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5531
  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5532
  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5533
  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5534
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5536
void Parker::park(bool isAbsolute, jlong time) {
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5537
  // Ideally we'd do something useful while spinning, such
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5538
  // as calling unpackTime().
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5539
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5540
  // Optional fast-path check:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5541
  // Return immediately if a permit is available.
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5542
  // We depend on Atomic::xchg() having full barrier semantics
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5543
  // 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
  5544
  if (Atomic::xchg(0, &_counter) > 0) return;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5545
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5546
  Thread* thread = Thread::current();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5547
  assert(thread->is_Java_thread(), "Must be JavaThread");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5548
  JavaThread *jt = (JavaThread *)thread;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5549
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5550
  // Optional optimization -- avoid state transitions if there's an interrupt pending.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5551
  // Check interrupt before trying to wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5552
  if (Thread::is_interrupted(thread, false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5553
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5554
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5555
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5556
  // Next, demultiplex/decode time arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5557
  timespec absTime;
6962
d49132ce025b 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 6420
diff changeset
  5558
  if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5559
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5560
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5561
  if (time > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5562
    unpackTime(&absTime, isAbsolute, time);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5563
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5565
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5566
  // Enter safepoint region
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5567
  // Beware of deadlocks such as 6317397.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5568
  // The per-thread Parker:: mutex is a classic leaf-lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5569
  // In particular a thread must never block on the Threads_lock while
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5570
  // holding the Parker:: mutex.  If safepoints are pending both the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5571
  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5572
  ThreadBlockInVM tbivm(jt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5573
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5574
  // Don't wait if cannot get lock since interference arises from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5575
  // unblocking.  Also. check interrupt before trying wait
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5576
  if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5577
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5580
  int status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5581
  if (_counter > 0)  { // no wait needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5582
    _counter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5583
    status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5584
    assert (status == 0, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5585
    // 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
  5586
    // 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
  5587
    OrderAccess::fence();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5588
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5589
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5590
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5591
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5592
  // Don't catch signals while blocked; let the running threads have the signals.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5593
  // (This allows a debugger to break into the running thread.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5594
  sigset_t oldsigs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5595
  sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5596
  pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5597
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5598
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5599
  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5600
  jt->set_suspend_equivalent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5601
  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5602
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5603
  if (time == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5604
    status = pthread_cond_wait (_cond, _mutex) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5605
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5606
    status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5607
    if (status != 0 && WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5608
      pthread_cond_destroy (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5609
      pthread_cond_init    (_cond, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5610
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5611
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5612
  assert_status(status == 0 || status == EINTR ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5613
                status == ETIME || status == ETIMEDOUT,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5614
                status, "cond_timedwait");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5616
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5617
  pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5618
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5619
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5620
  _counter = 0 ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5621
  status = pthread_mutex_unlock(_mutex) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5622
  assert_status(status == 0, status, "invariant") ;
15234
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5623
  // 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
  5624
  // correctly with each other and Java-level accesses.
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5625
  OrderAccess::fence();
ff1f01be5fbd 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 15096
diff changeset
  5626
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5627
  // If externally suspended while waiting, re-suspend
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5628
  if (jt->handle_special_suspend_equivalent_condition()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5629
    jt->java_suspend_self();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5631
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5632
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5633
void Parker::unpark() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5634
  int s, status ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5635
  status = pthread_mutex_lock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5636
  assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5637
  s = _counter;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5638
  _counter = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5639
  if (s < 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5640
     if (WorkAroundNPTLTimedWaitHang) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5641
        status = pthread_cond_signal (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5642
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5643
        status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5644
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5645
     } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5646
        status = pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5647
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5648
        status = pthread_cond_signal (_cond) ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5649
        assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5650
     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5651
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5652
    pthread_mutex_unlock(_mutex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5653
    assert (status == 0, "invariant") ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5654
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5655
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5656
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5657
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5658
extern char** environ;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5659
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5660
#ifndef __NR_fork
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5661
#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5662
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5663
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5664
#ifndef __NR_execve
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5665
#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5666
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5668
// Run the specified command in a separate process. Return its exit value,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5669
// or -1 on failure (e.g. can't fork a new process).
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5670
// Unlike system(), this function can be called from signal handler. It
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5671
// doesn't block SIGINT et al.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5672
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
  5673
  const char * argv[4] = {"sh", "-c", cmd, NULL};
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5674
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5675
  // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5676
  // pthread_atfork handlers and reset pthread library. All we need is a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5677
  // separate process to execve. Make a direct syscall to fork process.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5678
  // On IA64 there's no fork syscall, we have to use fork() and hope for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5679
  // the best...
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5680
  pid_t pid = NOT_IA64(syscall(__NR_fork);)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5681
              IA64_ONLY(fork();)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5682
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5683
  if (pid < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5684
    // fork failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5685
    return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5686
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5687
  } else if (pid == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5688
    // child process
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5690
    // execve() in LinuxThreads will call pthread_kill_other_threads_np()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5691
    // first to kill every thread on the thread list. Because this list is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5692
    // not reset by fork() (see notes above), execve() will instead kill
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5693
    // every thread in the parent process. We know this is the only thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5694
    // in the new process, so make a system call directly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5695
    // IA64 should use normal execve() from glibc to match the glibc fork()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5696
    // above.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5697
    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
  5698
    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5700
    // execve failed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5701
    _exit(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5702
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5703
  } else  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5704
    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5705
    // care about the actual exit code, for now.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5707
    int status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5708
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5709
    // Wait for the child process to exit.  This returns immediately if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5710
    // the child has already exited. */
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5711
    while (waitpid(pid, &status, 0) < 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5712
        switch (errno) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5713
        case ECHILD: return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5714
        case EINTR: break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5715
        default: return -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5716
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5717
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5718
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5719
    if (WIFEXITED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5720
       // The child exited normally; get its exit code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5721
       return WEXITSTATUS(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5722
    } else if (WIFSIGNALED(status)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5723
       // The child exited because of a signal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5724
       // The best value to return is 0x80 + signal number,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5725
       // because that is what all Unix shells do, and because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5726
       // it allows callers to distinguish between process exit and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5727
       // process death by signal.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5728
       return 0x80 + WTERMSIG(status);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5729
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5730
       // Unknown exit code; pass it through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5731
       return status;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5732
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5733
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  5734
}
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5735
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5736
// is_headless_jre()
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5737
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5738
// 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
  5739
// 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
  5740
//
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5741
// 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
  5742
// 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
  5743
//
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5744
bool os::is_headless_jre() {
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5745
    struct stat statbuf;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5746
    char buf[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5747
    char libmawtpath[MAXPATHLEN];
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5748
    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
  5749
    const char *new_xawtstr = "/libawt_xawt.so";
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5750
    char *p;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5751
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5752
    // Get path to libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5753
    os::jvm_path(buf, sizeof(buf));
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5754
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5755
    // Get rid of libjvm.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5756
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5757
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5758
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5759
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5760
    // Get rid of client or server
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5761
    p = strrchr(buf, '/');
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5762
    if (p == NULL) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5763
    else *p = '\0';
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5764
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5765
    // check xawt/libmawt.so
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5766
    strcpy(libmawtpath, buf);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5767
    strcat(libmawtpath, xawtstr);
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5768
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5769
11161
ec855b5a23c2 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 10739
diff changeset
  5770
    // check libawt_xawt.so
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5771
    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
  5772
    strcat(libmawtpath, new_xawtstr);
6176
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5773
    if (::stat(libmawtpath, &statbuf) == 0) return false;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5774
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5775
    return true;
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5776
}
4d9030fe341f 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 5922
diff changeset
  5777
13198
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5778
// Get the default path to the core file
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5779
// Returns the length of the string
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5780
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
  5781
  const char* p = get_current_directory(buffer, bufferSize);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5782
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5783
  if (p == NULL) {
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5784
    assert(p != NULL, "failed to get current directory");
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5785
    return 0;
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5786
  }
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5787
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5788
  return strlen(buffer);
271c557a7623 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 13195
diff changeset
  5789
}
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5790
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5791
#ifdef JAVASE_EMBEDDED
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5792
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5793
// 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
  5794
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5795
MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5796
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5797
// ctor
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5798
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5799
MemNotifyThread::MemNotifyThread(int fd): Thread() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5800
  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
  5801
  _fd = fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5802
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5803
  if (os::create_thread(this, os::os_thread)) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5804
    _memnotify_thread = this;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5805
    os::set_priority(this, NearMaxPriority);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5806
    os::start_thread(this);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5807
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5808
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5809
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5810
// Where all the work gets done
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5811
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5812
void MemNotifyThread::run() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5813
  assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5814
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5815
  // Set up the select arguments
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5816
  fd_set rfds;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5817
  if (_fd != -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5818
    FD_ZERO(&rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5819
    FD_SET(_fd, &rfds);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5820
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5821
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5822
  // 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
  5823
  while (1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5824
    // 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
  5825
    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
  5826
    if (rc == -1) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5827
      perror("select!\n");
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5828
      break;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5829
    } else if (rc) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5830
      //ssize_t free_before = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5831
      //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
  5832
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5833
      // 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
  5834
      // try to do something about that
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5835
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5836
      // 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
  5837
      if (!Universe::heap()->is_gc_active()) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5838
        Universe::heap()->collect(GCCause::_allocation_failure);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5839
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5840
        //ssize_t free_after = os::available_memory();
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5841
        //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
  5842
        //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
  5843
      }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5844
      // 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
  5845
      // 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
  5846
    }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5847
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5848
}
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5849
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5850
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5851
// 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
  5852
//
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5853
void MemNotifyThread::start() {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5854
  int    fd;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5855
  fd = open ("/dev/mem_notify", O_RDONLY, 0);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5856
  if (fd < 0) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5857
      return;
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5858
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5859
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5860
  if (memnotify_thread() == NULL) {
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5861
    new MemNotifyThread(fd);
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5862
  }
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5863
}
18025
b7bcf7497f93 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 17854
diff changeset
  5864
10025
57fe03f10cf2 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 10023
diff changeset
  5865
#endif // JAVASE_EMBEDDED