提交 9c0a4486 编写于 作者: A alanb

6993732: Remove the HPI

Reviewed-by: ohair, lancea, chegar, mduigou, mchung, mr
上级 b65a4810
...@@ -74,15 +74,6 @@ SCRIPT_SUFFIX = ...@@ -74,15 +74,6 @@ SCRIPT_SUFFIX =
CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required! CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required!
CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required! CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
#
# Default HPI libraries. Build will build only native, unless
# overriden at the make command line. This makes it convenient for
# people doing, say, a pthreads port -- they can create a posix
# directory here, and say "gnumake HPIS=posix" at the top
# level.
#
HPIS = native
# #
# Default optimization # Default optimization
# #
......
...@@ -74,15 +74,6 @@ SCRIPT_SUFFIX = ...@@ -74,15 +74,6 @@ SCRIPT_SUFFIX =
CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required! CC_OBJECT_OUTPUT_FLAG = -o #trailing blank required!
CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required! CC_PROGRAM_OUTPUT_FLAG = -o #trailing blank required!
#
# Default HPI libraries. Build will build only native unless
# overriden at the make command line. This makes it convenient for
# people doing, say, a pthreads port -- they can create a posix
# directory here, and say "gnumake HPIS=posix" at the top
# level.
#
HPIS = native
# #
# Java default optimization (-x04/-O2) etc. Applies to the VM. # Java default optimization (-x04/-O2) etc. Applies to the VM.
# #
......
...@@ -43,7 +43,6 @@ FDDLIBM_SUFFIX = lib ...@@ -43,7 +43,6 @@ FDDLIBM_SUFFIX = lib
# The suffix applied to scripts (.bat for windows, nothing for unix) # The suffix applied to scripts (.bat for windows, nothing for unix)
SCRIPT_SUFFIX = .bat SCRIPT_SUFFIX = .bat
HPIS = windows
# LIB_LOCATION, which for windows identifies where .exe files go, may be # LIB_LOCATION, which for windows identifies where .exe files go, may be
# set by each GNUmakefile. The default is BINDIR. # set by each GNUmakefile. The default is BINDIR.
ifndef LIB_LOCATION ifndef LIB_LOCATION
......
...@@ -271,10 +271,9 @@ DEMOSRCDIR = $(SHARE_SRC)/demo ...@@ -271,10 +271,9 @@ DEMOSRCDIR = $(SHARE_SRC)/demo
# An attempt is made to generate unique enough directories for the # An attempt is made to generate unique enough directories for the
# generated files to not have name collisisons. Most build units # generated files to not have name collisisons. Most build units
# defines PRODUCT (except Release.gmk), but then they may or may # defines PRODUCT (except Release.gmk), but then they may or may
# not define PACKAGE, THREADIR (only HPI uses this), PROGRAM, and # not define PACKAGE, PROGRAM, and LIBRARY. This code attempts to
# LIBRARY. This code chunk attempts to generate a unique # generate a unique OBJDIR/CLASSHDRDIR for each build unit based
# OBJDIR/CLASSHDRDIR for each build unit based on which of those # on which of those values are set within each build unit.
# values are set within each build unit.
UNIQUE_LOCATION_STRING = tmp UNIQUE_LOCATION_STRING = tmp
...@@ -298,10 +297,6 @@ ifneq ($(LIBRARY),) ...@@ -298,10 +297,6 @@ ifneq ($(LIBRARY),)
endif endif
endif endif
ifneq ($(THREADDIR),)
UNIQUE_LOCATION_STRING += /$(THREADDIR)
endif
# #
# Build units may or may not define MODULE. Default to "other". # Build units may or may not define MODULE. Default to "other".
# #
......
...@@ -222,7 +222,7 @@ ifeq ($(PLATFORM), windows) ...@@ -222,7 +222,7 @@ ifeq ($(PLATFORM), windows)
@# Remove certain *.lib files @# Remove certain *.lib files
$(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \ $(CD) $(JRE_MODULE_IMAGE_DIR)/lib && \
$(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \ $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
@# The Java Kernel JRE image ships with a special VM. It is not included @# The Java Kernel JRE image ships with a special VM. It is not included
@# in the full JRE image, so remove it. Also, is it only for 32-bit windows. @# in the full JRE image, so remove it. Also, is it only for 32-bit windows.
...@@ -415,8 +415,7 @@ endif # !windows ...@@ -415,8 +415,7 @@ endif # !windows
trim-module-image-jdk:: trim-module-image-jdk::
@# Remove tools that should not be part of SDK. @# Remove tools that should not be part of SDK.
for t in $(NOTJDKTOOLS); do \ for t in $(NOTJDKTOOLS); do \
$(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \ $(RM) $(JDK_MODULE_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX); \
$(JDK_MODULE_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \
done done
# Get list of Elf files in the jdk # Get list of Elf files in the jdk
......
...@@ -133,7 +133,6 @@ JRE_DOCFILES += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_IMAGE_DIR)/%$(TEXT_SUFFIX)) ...@@ -133,7 +133,6 @@ JRE_DOCFILES += $(JRE_NAMECHANGE_DOCLIST:%=$(JRE_IMAGE_DIR)/%$(TEXT_SUFFIX))
# absolute directory names: note, these must exist prior to build # absolute directory names: note, these must exist prior to build
# time - they are created in the main Makefile. # time - they are created in the main Makefile.
JRE_IMAGE_BINDIR = $(JRE_IMAGE_DIR)/bin JRE_IMAGE_BINDIR = $(JRE_IMAGE_DIR)/bin
JRE_IMAGE_THREADIR = $(JRE_IMAGE_DIR)/bin/*/native_threads
MAINMANIFEST = $(JDK_TOPDIR)/make/tools/manifest.mf MAINMANIFEST = $(JDK_TOPDIR)/make/tools/manifest.mf
BEANMANIFEST = $(JDK_TOPDIR)/make/javax/swing/beaninfo/manifest BEANMANIFEST = $(JDK_TOPDIR)/make/javax/swing/beaninfo/manifest
...@@ -802,7 +801,7 @@ ifeq ($(PLATFORM), windows) ...@@ -802,7 +801,7 @@ ifeq ($(PLATFORM), windows)
@# Remove certain *.lib files @# Remove certain *.lib files
$(CD) $(JRE_IMAGE_DIR)/lib && \ $(CD) $(JRE_IMAGE_DIR)/lib && \
$(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \ $(RM) java.$(LIB_SUFFIX) jvm.$(LIB_SUFFIX) \
hpi.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX) awt.$(LIB_SUFFIX) jawt.$(LIB_SUFFIX)
ifeq ($(ARCH_DATA_MODEL), 32) ifeq ($(ARCH_DATA_MODEL), 32)
@# The Java Kernel JRE image ships with a special VM. It is not included @# The Java Kernel JRE image ships with a special VM. It is not included
@# in the full JRE image, so remove it. Also, is it only for 32-bit windows. @# in the full JRE image, so remove it. Also, is it only for 32-bit windows.
...@@ -1089,8 +1088,7 @@ endif # !windows ...@@ -1089,8 +1088,7 @@ endif # !windows
trim-image-jdk:: trim-image-jdk::
@# Remove tools that should not be part of SDK. @# Remove tools that should not be part of SDK.
for t in $(NOTJDKTOOLS); do \ for t in $(NOTJDKTOOLS); do \
$(RM) $(JDK_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX) \ $(RM) $(JDK_IMAGE_DIR)/bin/$${t}$(EXE_SUFFIX); \
$(JDK_IMAGE_DIR)/bin/*/native_threads/$${t}$(EXE_SUFFIX); \
done done
# Get list of Elf files in the jdk # Get list of Elf files in the jdk
......
...@@ -34,7 +34,7 @@ include $(BUILDDIR)/common/Defs.gmk ...@@ -34,7 +34,7 @@ include $(BUILDDIR)/common/Defs.gmk
# #
# The order of subdirs here is important # The order of subdirs here is important
# #
SUBDIRS += hpi version jvm redist verify fdlibm java sun_nio jli main zip SUBDIRS += version jvm redist verify fdlibm java sun_nio jli main zip
# Others # Others
# Note: java_crw_demo java_hprof_demo are demos but must be delivered built in sdk # Note: java_crw_demo java_hprof_demo are demos but must be delivered built in sdk
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
# #
# #
# Makefile for native threads HPI. # Makefile for fdlibm
# #
# Note: # Note:
# The fdlibm libraries are built using special rules in Library.gmk. # The fdlibm libraries are built using special rules in Library.gmk.
......
#
# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Build HPI (Host Porting Interface) libraries
#
BUILDDIR = ../..
include $(BUILDDIR)/common/Defs.gmk
#
# Build specified the HPI implementations
#
SUBDIRS = $(HPIS)
include $(BUILDDIR)/common/Subdirs.gmk
all build clean clobber::
$(SUBDIRS-loop)
#
# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Shared files between the different threads types on Solaris. Be
# careful when including this, you must get your variables right.
#
#
# Common files on Solaris.
#
ifneq ($(PLATFORM), windows)
FILES_c += \
interrupt.c \
linker_md.c \
memory_md.c \
system_md.c \
hpi.c
endif
#
# Include paths can also be shared.
#
ifneq ($(PLATFORM), windows)
OTHER_INCLUDES += \
-I$(PLATFORM_SRC)/hpi/$(THREADDIR)/include \
-I$(PLATFORM_SRC)/hpi/include \
-I$(PLATFORM_SRC)/hpi/export \
-I$(SHARE_SRC)/hpi/include \
-I$(SHARE_SRC)/hpi/export
else
OTHER_INCLUDES += \
-I$(PLATFORM_SRC)/hpi/include \
-I$(PLATFORM_SRC)/hpi/export \
-I$(SHARE_SRC)/hpi/include \
-I$(SHARE_SRC)/hpi/export
endif
#
# Add to the default C and assembly file search paths. Clear any initial
# vpath settings to ensure that we don't look in unexpected places for HPI
# files.
#
vpath %.c
vpath %.c $(PLATFORM_SRC)/hpi/$(THREADDIR)/src
vpath %.c $(PLATFORM_SRC)/hpi/src
vpath %.c $(SHARE_SRC)/hpi/src
vpath %.s
vpath %.s $(PLATFORM_SRC)/hpi/$(THREADDIR)/src
vpath %.s $(PLATFORM_SRC)/hpi/src
#
# By default leave out locking statistics
#
ifneq ($(PLATFORM), windows)
LOCKSTATS = false
ifeq ($(LOCKSTATS), true)
CFLAGS_COMMON += -DLOCKSTATS
endif
endif
#
# Things that must be linked in.
#
ifneq ($(PLATFORM), windows)
OTHER_LDLIBS += $(LIBSOCKET) $(LIBNSL) $(LIBM) -ldl
endif
#
# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for native threads HPI.
#
BUILDDIR = ../../..
MODULE = base
LIBRARY = hpi
PRODUCT = java
THREADDIR = native_threads
LIB_LOCATION = $(LIBDIR)/$(LIBARCH)/$(THREADDIR)
include $(BUILDDIR)/common/Defs.gmk
#
# Native threads specific C and .s files.
#
FILES_c = \
monitor_md.c \
threads_md.c \
condvar_md.c \
interrupt_md.c \
mutex_md.c \
sys_api_td.c \
threads_$(PLATFORM).c
#
# Other files/flags shared between the HPIs.
#
include $(BUILDDIR)/java/hpi/hpi_common.gmk
#
# Rules for the .so file.
#
ifeq ($(PLATFORM), solaris)
ifneq ($(ARCH), amd64)
FILES_reorder += reorder-$(ARCH)
endif
endif
include $(BUILDDIR)/common/Mapfile-vers.gmk
include $(BUILDDIR)/common/Library.gmk
#
# HPI flags for native threads.
#
OTHER_CPPFLAGS += -D_REENTRANT -DNATIVE
ifeq ($(USE_PTHREADS),true)
OTHER_CPPFLAGS += -DUSE_PTHREADS
ifeq ($(MOOT_PRIORITIES),true)
OTHER_CPPFLAGS += -DMOOT_PRIORITIES
endif
LIBPOSIX4 = -lposix4
OTHER_LDLIBS += -lpthread $(LIBPOSIX4)
endif
HAVE_GETHRVTIME=true
ifeq ($(HAVE_GETHRVTIME),true)
OTHER_CPPFLAGS += -DHAVE_GETHRVTIME
endif
HAVE_FILIOH=true
ifeq ($(HAVE_FILIOH),true)
OTHER_CPPFLAGS += -DHAVE_FILIOH
endif
ifeq ($(NO_INTERRUPTIBLE_IO),true)
OTHER_CPPFLAGS += -DNO_INTERRUPTIBLE_IO
endif
#
# Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
SUNWprivate_1.1 {
global:
DLL_Initialize;
local:
*;
};
data = R0x2000;
text = LOAD ?RXO;
# Test Null
text: .text%_init;
text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj/threads_solaris.o;
text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj/system_md.o;
text: .text%DLL_Initialize;
text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj/hpi.o;
text: .text%sysBuildLibName;
text: .text%sysLoadLibrary;
text: .text%sysFindLibraryEntry;
text: .text%sysNativePath;
text: .text%sysOpen;
text: .text%sysSeek;
text: .text%lseek64_w;
# Test Exit
# Test Hello
# Test Sleep
# Test IntToString
# Test LoadToolkit
text: .text%sysAvailable;
text: .text%sysFfileMode;
text: .text%sysGetLastErrorString;
# Test LoadFrame
# Test LoadJFrame
# Test JHello
# SwingSet
data = R0x2000;
text = LOAD ?RXO;
# Test Null
text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj/threads_solaris.o;
text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj/system_md.o;
text: .text%DLL_Initialize;
text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj/hpi.o;
text: .text%sysBuildLibName;
text: .text%sysLoadLibrary;
text: .text%sysFindLibraryEntry;
text: .text%sysNativePath;
text: .text%sysOpen;
text: .text%sysFfileMode;
text: .text%sysSeek;
text: .text%lseek64_w;
text: .text%sysAvailable;
# Test Exit
# Test Hello
# Test Sleep
# Test IntToString
# Test LoadToolkit
text: .text%sysGetLastErrorString;
# Test LoadFrame
# Test LoadJFrame
# Test JHello
# SwingSet
data = R0x2000;
text = LOAD ?RXO;
# Test Null
text: .text%checkForCorrectLibthread: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/threads_solaris.o;
text: .text%init64IO: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/system_md.o;
text: .text%DLL_Initialize;
text: .text%GetInterface: OUTPUTDIR/tmp/java/hpi/native_threads/obj64/hpi.o;
text: .text%sysBuildLibName;
text: .text%sysLoadLibrary;
text: .text%sysFindLibraryEntry;
text: .text%sysNativePath;
text: .text%sysOpen;
text: .text%sysFfileMode;
text: .text%sysSeek;
text: .text%lseek64_w;
text: .text%sysAvailable;
# Test Exit
# Test Hello
# Test Sleep
# Test IntToString
# Test LoadToolkit
text: .text%sysGetLastErrorString;
# Test LoadFrame
# Test LoadJFrame
# Test JHello
# SwingSet
#
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation. Oracle designates this
# particular file as subject to the "Classpath" exception as provided
# by Oracle in the LICENSE file that accompanied this code.
#
# This code is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
# or visit www.oracle.com if you need additional information or have any
# questions.
#
#
# Makefile for Windows HPI DLL
#
BUILDDIR = ../../..
MODULE = base
LIBRARY = hpi
PRODUCT = java
THREADDIR = windows_threads
LIB_LOCATION = $(BINDIR)
include $(BUILDDIR)/common/Defs.gmk
# windows compiler flags
ifeq ($(PLATFORM),windows)
CPPFLAGS_DBG += -DLOGGING
endif
FILES_c = \
linker_md.c \
memory_md.c \
monitor_md.c \
path_md.c \
socket_md.c \
sys_api_md.c \
system_md.c \
threads_md.c \
hpi.c # trailing blank required!
JVMLIB =
JAVALIB =
OTHER_LCF = -export:DLL_Initialize
EXTRA_LIBS =
#
# Other files/flags shared between the HPIs.
#
include $(BUILDDIR)/java/hpi/hpi_common.gmk
#
# Rules for the .so file.
#
include $(BUILDDIR)/common/Library.gmk
...@@ -85,7 +85,6 @@ reorder.jar : $(REORDER_JAR) ...@@ -85,7 +85,6 @@ reorder.jar : $(REORDER_JAR)
libs.reorder : libs.reorder :
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
$(MAKE) LIBBLDDIR=java/zip LIBTMPDIR=sun/java.util.zip/zip reorder.lib $(MAKE) LIBBLDDIR=java/zip LIBTMPDIR=sun/java.util.zip/zip reorder.lib
$(MAKE) LIBBLDDIR=java/hpi/native LIBTMPDIR=java/hpi/native_threads reorder.lib
$(MAKE) LIBBLDDIR=java/java LIBTMPDIR=java/java.lang/java reorder.lib $(MAKE) LIBBLDDIR=java/java LIBTMPDIR=java/java.lang/java reorder.lib
$(MAKE) LIBBLDDIR=java/nio LIBTMPDIR=java/java.nio/nio reorder.lib $(MAKE) LIBBLDDIR=java/nio LIBTMPDIR=java/java.nio/nio reorder.lib
$(MAKE) LIBBLDDIR=sun/font LIBTMPDIR=sun/sun.awt.font/fontmanager reorder.lib $(MAKE) LIBBLDDIR=sun/font LIBTMPDIR=sun/sun.awt.font/fontmanager reorder.lib
...@@ -96,7 +95,6 @@ endif ...@@ -96,7 +95,6 @@ endif
libs.copy: libs.copy:
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
$(CP) $(OUTDIR)/reorder_java_zip-$(ARCH) ../../java/zip/reorder-$(ARCH) $(CP) $(OUTDIR)/reorder_java_zip-$(ARCH) ../../java/zip/reorder-$(ARCH)
$(CP) $(OUTDIR)/reorder_java_hpi_native-$(ARCH) ../../java/hpi/native/reorder-$(ARCH)
$(CP) $(OUTDIR)/reorder_java_java-$(ARCH) ../../java/java/reorder-$(ARCH) $(CP) $(OUTDIR)/reorder_java_java-$(ARCH) ../../java/java/reorder-$(ARCH)
$(CP) $(OUTDIR)/reorder_sun_font-$(ARCH) ../../sun/font/reorder-$(ARCH) $(CP) $(OUTDIR)/reorder_sun_font-$(ARCH) ../../sun/font/reorder-$(ARCH)
$(CP) $(OUTDIR)/reorder_sun_jpeg-$(ARCH) ../../sun/jpeg/reorder-$(ARCH) $(CP) $(OUTDIR)/reorder_sun_jpeg-$(ARCH) ../../sun/jpeg/reorder-$(ARCH)
......
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_BOOL_H_
#define _JAVASOFT_BOOL_H_
#undef TRUE
#undef FALSE
typedef enum {
FALSE = 0,
TRUE = 1
} bool_t;
#endif /* !_JAVASOFT_BOOL_H_ */
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_DLL_H_
#define _JAVASOFT_DLL_H_
#include <jni.h>
/* DLL.H: A common interface for helper DLLs loaded by the VM.
* Each library exports the main entry point "DLL_Initialize". Through
* that function the programmer can obtain a function pointer which has
* type "GetInterfaceFunc." Through the function pointer the programmer
* can obtain other interfaces supported in the DLL.
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef jint (JNICALL * GetInterfaceFunc)
(void **intfP, const char *name, jint ver);
jint JNICALL DLL_Initialize(GetInterfaceFunc *, void *args);
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_DLL_H_ */
/*
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Host Porting Interface. This defines the "porting layer" for
* POSIX.1 compliant operating systems.
*/
#ifndef _JAVASOFT_HPI_H_
#define _JAVASOFT_HPI_H_
#include <stdio.h>
#include <sys/types.h>
#include "jni.h"
#include "bool.h"
#include "hpi_md.h"
#include "dll.h"
#ifdef __solaris__
#define SSIZE_T ssize_t
#else
#ifdef _LP64
#define SSIZE_T ssize_t
#else
#define SSIZE_T int
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* memory allocations
*/
typedef struct {
/*
* Malloc must return a unique pointer if size == 0.
*/
void * (*Malloc)(size_t size);
void * (*Realloc)(void *ptr, size_t new_size);
/*
* Free must allow ptr == NULL to be a no-op.
*/
void (*Free)(void *ptr);
/*
* Calloc must return a unique pointer for if
* n_item == 0 || item_size == 0.
*/
void * (*Calloc)(size_t n_item, size_t item_size);
char * (*Strdup)(const char *str);
void * (*MapMem)(size_t req_size, size_t *maped_size);
void * (*UnmapMem)(void *req_addr, size_t req_size, size_t *unmap_size);
/*
* CommitMem should round the ptr down to the nearest page and
* round the size up to the nearest page so that the committed
* region is at least as large as the requested region.
*/
void * (*CommitMem)(void *ptr, size_t size, size_t *actual);
/*
* sysDecommitMem should round the ptr up to the nearest page and
* round the size down to the nearest page so that the decommitted
* region is no greater than the requested region.
*/
void * (*DecommitMem)(void *ptr, size_t size, size_t *actual);
#define HPI_PAGE_ALIGNMENT (64 * 1024)
void * (*AllocBlock)(size_t size, void **headP);
void (*FreeBlock)(void *head);
} HPI_MemoryInterface;
/*
* dynamic linking libraries
*/
typedef struct {
void (*BuildLibName)(char *buf, int buf_len, char *path, char *name);
int (*BuildFunName)(char *name, int name_len, int arg_size, int en_idx);
void * (*LoadLibrary)(const char *name, char *err_buf, int err_buflen);
void (*UnloadLibrary)(void *lib);
void * (*FindLibraryEntry)(void *lib, const char *name);
} HPI_LibraryInterface;
typedef void (*signal_handler_t)(int sig, void *siginfo, void *context);
#define HPI_SIG_DFL (signal_handler_t)0
#define HPI_SIG_ERR (signal_handler_t)-1
#define HPI_SIG_IGN (signal_handler_t)1
typedef struct {
char *name; /* name such as green/native threads. */
int isMP;
} HPI_SysInfo;
typedef struct {
HPI_SysInfo * (*GetSysInfo)(void);
long (*GetMilliTicks)(void);
jlong (*TimeMillis)(void);
signal_handler_t (*Signal)(int sig, signal_handler_t handler);
void (*Raise)(int sig);
void (*SignalNotify)(int sig);
int (*SignalWait)(void);
int (*Shutdown)(void);
int (*SetLoggingLevel)(int level);
bool_t (*SetMonitoringOn)(bool_t on);
int (*GetLastErrorString)(char *buf, int len);
} HPI_SystemInterface;
/*
* threads and monitors
*/
typedef struct sys_thread sys_thread_t;
typedef struct sys_mon sys_mon_t;
#define HPI_OK 0
#define HPI_ERR -1
#define HPI_INTRPT -2 /* Operation was interrupted */
#define HPI_TIMEOUT -3 /* A timer ran out */
#define HPI_NOMEM -5 /* Ran out of memory */
#define HPI_NORESOURCE -6 /* Ran out of some system resource */
/* There are three basic states: RUNNABLE, MONITOR_WAIT, and CONDVAR_WAIT.
* When the thread is suspended in any of these states, the
* HPI_THREAD_SUSPENDED bit will be set
*/
enum {
HPI_THREAD_RUNNABLE = 1,
HPI_THREAD_MONITOR_WAIT,
HPI_THREAD_CONDVAR_WAIT
};
#define HPI_MINIMUM_PRIORITY 1
#define HPI_MAXIMUM_PRIORITY 10
#define HPI_NORMAL_PRIORITY 5
#define HPI_THREAD_SUSPENDED 0x8000
#define HPI_THREAD_INTERRUPTED 0x4000
typedef struct {
sys_thread_t *owner;
long entry_count;
sys_thread_t **monitor_waiters;
sys_thread_t **condvar_waiters;
int sz_monitor_waiters;
int sz_condvar_waiters;
int n_monitor_waiters;
int n_condvar_waiters;
} sys_mon_info;
typedef struct {
int (*ThreadBootstrap)(sys_thread_t **tidP,
sys_mon_t **qlockP,
int nReservedBytes);
int (*ThreadCreate)(sys_thread_t **tidP,
long stk_size,
void (*func)(void *),
void *arg);
sys_thread_t * (*ThreadSelf)(void);
void (*ThreadYield)(void);
int (*ThreadSuspend)(sys_thread_t *tid);
int (*ThreadResume)(sys_thread_t *tid);
int (*ThreadSetPriority)(sys_thread_t *tid, int prio);
int (*ThreadGetPriority)(sys_thread_t *tid, int *prio);
void * (*ThreadStackPointer)(sys_thread_t *tid);
void * (*ThreadStackTop)(sys_thread_t *tid);
long * (*ThreadRegs)(sys_thread_t *tid, int *regs);
int (*ThreadSingle)(void);
void (*ThreadMulti)(void);
int (*ThreadEnumerateOver)(int (*func)(sys_thread_t *, void *),
void *arg);
int (*ThreadCheckStack)(void);
void (*ThreadPostException)(sys_thread_t *tid, void *arg);
void (*ThreadInterrupt)(sys_thread_t *tid);
int (*ThreadIsInterrupted)(sys_thread_t *tid, int clear);
int (*ThreadAlloc)(sys_thread_t **tidP);
int (*ThreadFree)(void);
jlong (*ThreadCPUTime)(void);
int (*ThreadGetStatus)(sys_thread_t *tid, sys_mon_t **monitor);
void * (*ThreadInterruptEvent)(void);
void * (*ThreadNativeID)(sys_thread_t *tid);
/* These three functions are used by the CPU time profiler.
* sysThreadIsRunning determines whether the thread is running (not just
* runnable). It is only safe to call this function after calling
* sysThreadProfSuspend.
*/
bool_t (*ThreadIsRunning)(sys_thread_t *tid);
void (*ThreadProfSuspend)(sys_thread_t *tid);
void (*ThreadProfResume)(sys_thread_t *tid);
int (*AdjustTimeSlice)(int ms);
size_t (*MonitorSizeof)(void);
int (*MonitorInit)(sys_mon_t *mid);
int (*MonitorDestroy)(sys_mon_t *mid);
int (*MonitorEnter)(sys_thread_t *self, sys_mon_t *mid);
bool_t (*MonitorEntered)(sys_thread_t *self, sys_mon_t *mid);
int (*MonitorExit)(sys_thread_t *self, sys_mon_t *mid);
int (*MonitorNotify)(sys_thread_t *self, sys_mon_t *mid);
int (*MonitorNotifyAll)(sys_thread_t *self, sys_mon_t *mid);
int (*MonitorWait)(sys_thread_t *self, sys_mon_t *mid, jlong ms);
bool_t (*MonitorInUse)(sys_mon_t *mid);
sys_thread_t * (*MonitorOwner)(sys_mon_t *mid);
int (*MonitorGetInfo)(sys_mon_t *mid, sys_mon_info *info);
} HPI_ThreadInterface;
/*
* files
*/
#define HPI_FILETYPE_REGULAR (0)
#define HPI_FILETYPE_DIRECTORY (1)
#define HPI_FILETYPE_OTHER (2)
typedef struct {
char * (*NativePath)(char *path);
int (*FileType)(const char *path);
int (*Open)(const char *name, int openMode, int filePerm);
int (*Close)(int fd);
jlong (*Seek)(int fd, jlong offset, int whence);
int (*SetLength)(int fd, jlong length);
int (*Sync)(int fd);
int (*Available)(int fd, jlong *bytes);
size_t (*Read)(int fd, void *buf, unsigned int nBytes);
size_t (*Write)(int fd, const void *buf, unsigned int nBytes);
int (*FileSizeFD)(int fd, jlong *size);
} HPI_FileInterface;
/*
* sockets
*/
struct sockaddr;
struct hostent;
typedef struct {
int (*Close)(int fd);
long (*Available)(int fd, jint *pbytes);
int (*Connect)(int fd, struct sockaddr *him, int len);
int (*Accept)(int fd, struct sockaddr *him, int *len);
SSIZE_T (*SendTo)(int fd, char *buf, int len, int flags,
struct sockaddr *to, int tolen);
SSIZE_T (*RecvFrom)(int fd, char *buf, int nbytes, int flags,
struct sockaddr *from, int *fromlen);
int (*Listen)(int fd, int count);
SSIZE_T (*Recv)(int fd, char *buf, int nBytes, int flags);
SSIZE_T (*Send)(int fd, char *buf, int nBytes, int flags);
int (*Timeout)(int fd, long timeout);
struct hostent * (*GetHostByName)(char *hostname);
int (*Socket)(int domain, int type, int protocol);
int (*SocketShutdown)(int fd, int howto);
int (*Bind)(int fd, struct sockaddr *him, int len);
int (*GetSocketName)(int fd, struct sockaddr *him, int *len);
int (*GetHostName)(char *hostname, int namelen);
struct hostent * (*GetHostByAddr)(const char *hostname, int len, int type);
int (*SocketGetOption)(int fd, int level, int optname, char *optval, int *optlen);
int (*SocketSetOption)(int fd, int level, int optname, const char *optval, int optlen);
struct protoent * (*GetProtoByName)(char* name);
} HPI_SocketInterface;
/*
* callbacks.
*/
typedef struct vm_calls {
int (*jio_fprintf)(FILE *fp, const char *fmt, ...);
void (*panic)(const char *fmt, ...);
void (*monitorRegister)(sys_mon_t *mid, char *info_str);
void (*monitorContendedEnter)(sys_thread_t *self, sys_mon_t *mid);
void (*monitorContendedEntered)(sys_thread_t *self, sys_mon_t *mid);
void (*monitorContendedExit)(sys_thread_t *self, sys_mon_t *mid);
} vm_calls_t;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_HPI_H_ */
/*
* Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_HPI_IMPL_H_
#define _JAVASOFT_HPI_IMPL_H_
#include "hpi.h"
#ifdef __cplusplus
extern "C" {
#endif
#include "vm_calls.h"
extern int nReservedBytes;
sys_thread_t *allocThreadBlock(void);
void freeThreadBlock(sys_thread_t *tid);
int threadBootstrapMD(sys_thread_t **tid, sys_mon_t **lockP, int nb);
HPI_SysInfo *sysGetSysInfo(void);
long sysGetMilliTicks(void);
jlong sysTimeMillis(void);
signal_handler_t sysSignal(int sig, signal_handler_t handler);
void sysRaise(int sig);
void sysSignalNotify(int sig);
int sysSignalWait(void);
int sysShutdown(void);
int sysSetLoggingLevel(int level);
bool_t sysSetMonitoringOn(bool_t on);
int sysGetLastErrorString(char *buf, int len);
void * sysMalloc(size_t);
void * sysRealloc(void*, size_t);
void sysFree(void*);
void * sysCalloc(size_t, size_t);
char * sysStrdup(const char * string);
void * sysMapMem(size_t, size_t *);
void * sysUnmapMem(void *, size_t, size_t *);
void * sysCommitMem(void * ptr, size_t size, size_t * actual);
void * sysDecommitMem(void * ptr, size_t size, size_t * actual);
void * sysAllocBlock(size_t, void**);
void sysFreeBlock(void *);
void sysBuildLibName(char *, int, char *, char *);
int sysBuildFunName(char *, int, int, int);
void * sysLoadLibrary(const char *, char *err_buf, int err_buflen);
void sysUnloadLibrary(void *);
void * sysFindLibraryEntry(void *, const char *);
int sysThreadBootstrap(sys_thread_t **, sys_mon_t **, int);
int sysThreadCreate(sys_thread_t **,
long,
void (*)(void *),
void *arg);
void sysThreadExit(void);
sys_thread_t * sysThreadSelf(void);
void sysThreadYield(void);
int sysThreadSuspend(sys_thread_t *);
int sysThreadResume(sys_thread_t *);
int sysThreadSetPriority(sys_thread_t *, int);
int sysThreadGetPriority(sys_thread_t *, int *);
void * sysThreadStackPointer(sys_thread_t *);
void * sysThreadStackTop(sys_thread_t *);
long * sysThreadRegs(sys_thread_t *, int *);
int sysThreadSingle(void);
void sysThreadMulti(void);
int sysThreadEnumerateOver(int (*)(sys_thread_t *, void *), void *);
int sysThreadCheckStack(void);
void sysThreadPostException(sys_thread_t *, void *);
void sysThreadInterrupt(sys_thread_t *);
int sysThreadIsInterrupted(sys_thread_t *, int);
int sysThreadAlloc(sys_thread_t **);
int sysThreadFree(void);
size_t sysThreadSizeof(void);
jlong sysThreadCPUTime(void);
int sysThreadGetStatus(sys_thread_t *, sys_mon_t **);
int sysAdjustUserThreadCount(int delta);
bool_t sysThreadIsRunning(sys_thread_t *);
void sysThreadProfSuspend(sys_thread_t *);
void sysThreadProfResume(sys_thread_t *);
int sysAdjustTimeSlice(int);
int sysThreadEnumerateOver(int (*f)(sys_thread_t *, void *), void *arg);
void * sysThreadInterruptEvent(void);
void * sysThreadNativeID(sys_thread_t *);
size_t sysMonitorSizeof(void);
int sysMonitorInit(sys_mon_t *);
int sysMonitorDestroy(sys_mon_t *);
int sysMonitorEnter(sys_thread_t *, sys_mon_t *);
bool_t sysMonitorEntered(sys_thread_t *, sys_mon_t *);
int sysMonitorExit(sys_thread_t *, sys_mon_t *);
int sysMonitorNotify(sys_thread_t *, sys_mon_t *);
int sysMonitorNotifyAll(sys_thread_t *, sys_mon_t *);
int sysMonitorWait(sys_thread_t *, sys_mon_t *, jlong);
bool_t sysMonitorInUse(sys_mon_t *);
sys_thread_t * sysMonitorOwner(sys_mon_t *);
int sysMonitorGetInfo(sys_mon_t *, sys_mon_info *);
char *sysNativePath(char *path);
int sysFileType(const char *path);
int sysOpen(const char *name, int openMode, int filePerm);
int sysClose(int fd);
jlong sysSeek(int fd, jlong offset, int whence);
int sysSetLength(int fd, jlong length);
int sysSync(int fd);
int sysAvailable(int fd, jlong *bytes);
size_t sysRead(int fd, void *buf, unsigned int nBytes);
size_t sysWrite(int fd, const void *buf, unsigned int nBytes);
int sysFileSizeFD(int fd, jlong *size);
int sysSocketClose(int fd);
int sysSocketShutdown(int fd, int howto);
long sysSocketAvailable(int fd, jint *pbytes);
int sysConnect(int fd, struct sockaddr *him, int len);
int sysBind(int fd, struct sockaddr *him, int len);
int sysAccept(int fd, struct sockaddr *him, int *len);
int sysGetSockName(int fd, struct sockaddr *him, int *len);
#ifdef _LP64
ssize_t sysSendTo(int fd, char *buf, int len, int flags, struct sockaddr *to,
int tolen);
ssize_t sysRecvFrom(int fd, char *buf, int nbytes, int flags,
struct sockaddr *from, int *fromlen);
ssize_t sysRecv(int fd, char *buf, int nBytes, int flags);
ssize_t sysSend(int fd, char *buf, int nBytes, int flags);
#else
int sysSendTo(int fd, char *buf, int len, int flags, struct sockaddr *to,
int tolen);
int sysRecvFrom(int fd, char *buf, int nbytes, int flags,
struct sockaddr *from, int *fromlen);
int sysRecv(int fd, char *buf, int nBytes, int flags);
int sysSend(int fd, char *buf, int nBytes, int flags);
#endif
int sysListen(int fd, int count);
int sysTimeout(int fd, long timeout);
int sysGetHostName(char* name, int namelen);
struct hostent *sysGetHostByAddr(const char* name, int len, int type);
struct hostent *sysGetHostByName(char *hostname);
int sysSocket(int domain, int type, int protocol);
int sysGetSockOpt(int fd, int level, int optname, char *optval, int *optlen);
int sysSetSockOpt(int fd, int level, int optname, const char *optval, int optlen);
struct protoent * sysGetProtoByName(char* name);
#define SYS_SIG_DFL HPI_SIG_DFL
#define SYS_SIG_ERR HPI_SIG_ERR
#define SYS_SIG_IGN HPI_SIG_IGN
#define SYS_OK HPI_OK
#define SYS_ERR HPI_ERR
#define SYS_INTRPT HPI_INTRPT
#define SYS_TIMEOUT HPI_TIMEOUT
#define SYS_NOMEM HPI_NOMEM
#define SYS_NORESOURCE HPI_NORESOURCE
#define SYS_THREAD_RUNNABLE HPI_THREAD_RUNNABLE
#define SYS_THREAD_MONITOR_WAIT HPI_THREAD_MONITOR_WAIT
#define SYS_THREAD_CONDVAR_WAIT HPI_THREAD_CONDVAR_WAIT
#define MinimumPriority HPI_MINIMUM_PRIORITY
#define MaximumPriority HPI_MAXIMUM_PRIORITY
#define NormalPriority HPI_NORMAL_PRIORITY
#define SYS_THREAD_SUSPENDED HPI_THREAD_SUSPENDED
#define PAGE_ALIGNMENT HPI_PAGE_ALIGNMENT
#define SYS_TIMEOUT_INFINITY HPI_TIMEOUT_INFINITY
#define SYS_FILETYPE_REGULAR HPI_FILETYPE_REGULAR
#define SYS_FILETYPE_DIRECTORY HPI_FILETYPE_DIRECTORY
#define SYS_FILETYPE_OTHER HPI_FILETYPE_OTHER
typedef void *stackp_t;
/* global vars */
extern int logging_level;
extern bool_t profiler_on;
#ifdef __cplusplus
}
#endif
#endif /* !_JAVASOFT_HPI_IMPL_H_ */
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_VM_CALLS_H_
#define _JAVASOFT_VM_CALLS_H_
/* This file defines the function table and macros exported from the VM
* for the implementation of HPI.
*/
extern vm_calls_t *vm_calls;
#define VM_CALLS_READY() vm_calls
#define VM_CALL(f) (vm_calls->f)
#undef sysAssert
#ifdef DEBUG
#define sysAssert(expression) { \
if (!(expression)) { \
vm_calls->panic \
("\"%s\", line %d: assertion failure\n", __FILE__, __LINE__); \
} \
}
#else
#define sysAssert(expression) ((void) 0)
#endif
#ifdef LOGGING
#define Log(level, message) { \
if (vm_calls && level <= logging_level) \
vm_calls->jio_fprintf(stderr, message); \
}
#define Log1(level, message, x1) { \
if (vm_calls && level <= logging_level) \
vm_calls->jio_fprintf(stderr, message, (x1)); \
}
#define Log2(level, message, x1, x2) { \
if (vm_calls && level <= logging_level) \
vm_calls->jio_fprintf(stderr, message, (x1), (x2)); \
}
#define Log3(level, message, x1, x2, x3) { \
if (vm_calls && level <= logging_level) \
vm_calls->jio_fprintf(stderr, message, (x1), (x2), (x3)); \
}
#define Log4(level, message, x1, x2, x3, x4) { \
if (vm_calls && level <= logging_level) \
vm_calls->jio_fprintf(stderr, message, (x1), (x2), (x3), (x4)); \
}
#else
#define Log(level, message) ((void) 0)
#define Log1(level, message, x1) ((void) 0)
#define Log2(level, message, x1, x2) ((void) 0)
#define Log3(level, message, x1, x2, x3) ((void) 0)
#define Log4(level, message, x1, x2, x3, x4) ((void) 0)
#endif /* LOGGING */
#endif /* !_JAVASOFT_VM_CALLS_H_ */
/*
* Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include <string.h>
#include "hpi_impl.h"
#include "threads_md.h"
int logging_level = 0;
bool_t profiler_on = FALSE;
int sysSetLoggingLevel(int level)
{
int old = logging_level;
logging_level = level;
return old;
}
bool_t sysSetMonitoringOn(bool_t s)
{
bool_t old = profiler_on;
profiler_on = s;
return old;
}
int nReservedBytes;
sys_thread_t *allocThreadBlock()
{
char *p = sysCalloc(nReservedBytes + sizeof(sys_thread_t), 1);
if (p == NULL) {
return NULL;
}
return (sys_thread_t *)(p + nReservedBytes);
}
void freeThreadBlock(sys_thread_t *tid)
{
sysFree((char *)tid - nReservedBytes);
}
vm_calls_t *vm_calls = NULL;
static HPI_MemoryInterface hpi_memory_interface = {
sysMalloc,
sysRealloc,
sysFree,
sysCalloc,
sysStrdup,
sysMapMem,
sysUnmapMem,
sysCommitMem,
sysDecommitMem,
sysAllocBlock,
sysFreeBlock,
};
static HPI_LibraryInterface hpi_library_interface = {
sysBuildLibName,
sysBuildFunName,
sysLoadLibrary,
sysUnloadLibrary,
sysFindLibraryEntry,
};
static HPI_SystemInterface hpi_system_interface = {
sysGetSysInfo,
sysGetMilliTicks,
sysTimeMillis,
sysSignal,
sysRaise,
sysSignalNotify,
sysSignalWait,
sysShutdown,
sysSetLoggingLevel,
sysSetMonitoringOn,
sysGetLastErrorString
};
static HPI_ThreadInterface hpi_thread_interface = {
sysThreadBootstrap,
sysThreadCreate,
sysThreadSelf,
sysThreadYield,
sysThreadSuspend,
sysThreadResume,
sysThreadSetPriority,
sysThreadGetPriority,
sysThreadStackPointer,
sysThreadStackTop,
sysThreadRegs,
sysThreadSingle,
sysThreadMulti,
sysThreadEnumerateOver,
sysThreadCheckStack,
sysThreadPostException,
sysThreadInterrupt,
sysThreadIsInterrupted,
sysThreadAlloc,
sysThreadFree,
sysThreadCPUTime,
sysThreadGetStatus,
sysThreadInterruptEvent,
sysThreadNativeID,
sysThreadIsRunning,
sysThreadProfSuspend,
sysThreadProfResume,
sysAdjustTimeSlice,
sysMonitorSizeof,
sysMonitorInit,
sysMonitorDestroy,
sysMonitorEnter,
sysMonitorEntered,
sysMonitorExit,
sysMonitorNotify,
sysMonitorNotifyAll,
sysMonitorWait,
sysMonitorInUse,
sysMonitorOwner,
sysMonitorGetInfo,
};
static HPI_FileInterface hpi_file_interface = {
sysNativePath,
sysFileType,
sysOpen,
sysClose,
sysSeek,
sysSetLength,
sysSync,
sysAvailable,
sysRead,
sysWrite,
sysFileSizeFD
};
static HPI_SocketInterface hpi_socket_interface = {
sysSocketClose,
sysSocketAvailable,
sysConnect,
sysAccept,
sysSendTo,
sysRecvFrom,
sysListen,
sysRecv,
sysSend,
sysTimeout,
sysGetHostByName,
sysSocket,
sysSocketShutdown,
sysBind,
sysGetSockName,
sysGetHostName,
sysGetHostByAddr,
sysGetSockOpt,
sysSetSockOpt,
sysGetProtoByName,
};
static jint JNICALL
GetInterface(void **intfP, const char *name, jint version)
{
*intfP = NULL;
if (version != 1) {
return -1;
}
if (strcmp(name, "Memory") == 0) {
*intfP = &hpi_memory_interface;
return 0;
}
if (strcmp(name, "Library") == 0) {
*intfP = &hpi_library_interface;
return 0;
}
if (strcmp(name, "System") == 0) {
*intfP = &hpi_system_interface;
return 0;
}
if (strcmp(name, "Thread") == 0) {
*intfP = &hpi_thread_interface;
return 0;
}
if (strcmp(name, "File") == 0) {
*intfP = &hpi_file_interface;
return 0;
}
if (strcmp(name, "Socket") == 0) {
*intfP = &hpi_socket_interface;
return 0;
}
return -2;
}
jint JNICALL
DLL_Initialize(GetInterfaceFunc *gi, void *args)
{
vm_calls = args;
*gi = GetInterface;
return SYS_OK;
}
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Solaris-dependent byte order include
*/
#ifndef _JAVASOFT_SOLARIS_BYTE_MD_H_
#define _JAVASOFT_SOLARIS_BYTE_MD_H_
#include <netinet/in.h>
#endif /* !_JAVASOFT_SOLARIS_BYTE_MD_H_ */
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_HPI_MD_H_
#define _JAVASOFT_HPI_MD_H_
#include "timeval_md.h"
#include "io_md.h"
#include "path_md.h"
#include "byteorder_md.h"
#define HPI_TIMEOUT_INFINITY ((jlong)(-1))
#endif /* !_JAVASOFT_HPI_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Solaris-dependent I/O
*/
#ifndef _JAVASOFT_SOLARIS_IO_MD_H_
#define _JAVASOFT_SOLARIS_IO_MD_H_
#include <sys/param.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define LINE_SEPARATOR "\n"
/* file system macros moved to sysmacros_md.h */
#endif /* !_JAVASOFT_SOLARIS_IO_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Solaris-dependent search path definitions and API
*/
#ifndef _JAVASOFT_SOLARIS_PATH_MD_H_
#define _JAVASOFT_SOLARIS_PATH_MD_H_
#define PATH_SEPARATOR ":"
#define PATH_CURDIR "."
#define DIR_SEPARATOR '/'
#define LOCAL_DIR_SEPARATOR '/'
#endif /* !_JAVASOFT_SOLARIS_PATH_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_SOLARIS_TIMEVAL_H_
#define _JAVASOFT_SOLARIS_TIMEVAL_H_
typedef struct {
long tv_sec; /* seconds */
long tv_usec; /* microseconds (NOT milliseconds) */
} timeval_t;
#endif /* !_JAVASOFT_SOLARIS_TIMEVAL_H_ */
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_SOLARIS_HPI_INIT_H_
#define _JAVASOFT_SOLARIS_HPI_INIT_H_
#ifndef NATIVE
extern void InitializeSbrk(void);
extern void InitializeAsyncIO(void);
extern void InitializeHelperThreads(void);
#endif /* NATIVE */
extern void InitializeMem(void);
#endif /* _JAVASOFT_SOLARIS_HPI_INIT_H_ */
/*
* Copyright (c) 1994, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Interrupt dispatch interface
*/
#ifndef _JAVASOFT_INTERRUPT_H_
#define _JAVASOFT_INTERRUPT_H_
/*
* Type definitions.
*/
/*-
* A function that handles interrupt dispatch requests is of type
* intr_handler_t. This type definition is mostly for convenience.
* A declaration of a handler function, should look like this:
*
* void myHandler(int interrupt, void *siginfo, void *context, void *arg);
*
* An intr_handler_t is constrained:
*
* - It runs on the exception stack.
* - It cannot yield.
* - It cannot allocate/free memory.
* - It can only call interrupt-safe routines.
*
* "arg" is set to the "handlerArg" specified in intrRegister().
*/
typedef void (*intr_handler_t)(int interrupt, void *siginfo,
void *context, void *arg);
/*
* Routines.
*/
/* Initialize the interrupt system */
void intrInit(void);
/* Set a handler for a particular interrupt */
signal_handler_t intrRegister(int interrupt, intr_handler_t handler,
void *handlerArg);
/* Dispatch an interrupt (called from the low-level handlers) */
void intrDispatch(int interrupt, void *siginfo, void *context);
/*-
* The target specific header file should define the following
*
* Constants
*
* N_INTERRUPTS - The number of interrupt channels. These
* are numbered from 0 to (N_INTERRUPTS - 1).
*/
#ifdef __linux__
#define N_INTERRUPTS NSIG /* 0 to NSIG - 1*/
#else
#define N_INTERRUPTS 32 /* 0 to 31 */
#endif
/*-
* Routines/Macros that control whether interrupts are enabled or
* not.
*
* void intrLock(void) - Disable all interrupts.
* void intrUnlock(void) - Enable all interrupts.
*
* Note: intrLock()/intrUnlock() pairs can be nested.
*
*/
void intrLock(void);
void intrUnlock(void);
/*-
* intrInitMD() --
* Initialize the machine-dependant interrupt software.
*
* This routine should leave the all interrupts disabled as if
* one (1) intrLock() had been called. At the end of the
* bootstrap, a single intrUnlock(), will be called to turn
* interrupts on.
*/
void intrInitMD(void);
#if defined(__solaris__) && !defined(SA_SIGINFO)
#error signal.h has not been included?
#endif
#ifdef SA_SIGINFO
/* Thread implementation dependent interrupt dispatcher. */
void intrDispatchMD(int sig, siginfo_t *info, void *uc);
#else
void intrDispatchMD(int sig);
#endif
/* Whether the signal is used by the HPI implementation */
bool_t intrInUse(int sig);
#endif /* !_JAVASOFT_INTERRUPT_H_ */
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_LARGEFILE_SUPPORT_H_
#define _JAVASOFT_LARGEFILE_SUPPORT_H_
#ifdef __solaris__
#include "largefile_solaris.h"
#endif
#ifdef __linux__
#include "largefile_linux.h"
#endif
/*
* Prototypes for wrappers that we define. These wrapper functions
* are low-level I/O routines that will use 64 bit versions if
* available, else revert to the 32 bit ones.
*/
extern off64_t lseek64_w(int fd, off64_t offset, int whence);
extern int fstat64_w(int fd, struct stat *buf);
extern int ftruncate64_w(int fd, off64_t length);
extern int open64_w(const char *path, int oflag, int mode);
/* This is defined in system_md.c */
extern int sysFfileMode(int fd, int* mode);
#endif /* _JAVASOFT_LARGEFILE_SUPPORT_H_ */
/*
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_LINUX_LARGEFILE_SUPPORT_H_
#define _JAVASOFT_LINUX_LARGEFILE_SUPPORT_H_
/*
* For building on glibc-2.0 we need to define stat64 here.
*/
#include <sys/types.h>
#include <sys/stat.h>
#endif /* _JAVASOFT_LINUX_LARGEFILE_SUPPORT_H_ */
/*
* Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_SOLARIS_LARGEFILE_SUPPORT_H_
#define _JAVASOFT_SOLARIS_LARGEFILE_SUPPORT_H_
#include <sys/stat.h>
#include <sys/types.h>
/**
* This file contains the definitions for providing 64 bit File I/O support.
*/
#if !defined(_LFS_LARGEFILE) || !_LFS_LARGEFILE
#ifdef __GLIBC__
typedef jlong longlong_t;
#endif
/*
* This definition is from Solaris 2.6; it is required by systems that do not
* support large files (e.g., Solaris 2.5.1).
*/
typedef longlong_t off64_t; /* offsets within files */
#ifdef __GLIBC__
/* Doesn't matter what these are, there is no 64 bit support. */
typedef int u_longlong_t;
typedef int timestruc_t;
#define _ST_FSTYPSZ 1
#endif /* __GLIBC__ */
/*
* The stat64 structure must be provided on systems without large file
* support (e.g., Solaris 2.5.1). These definitions are from Solaris 2.6
* sys/stat.h and sys/types.h.
*/
typedef u_longlong_t ino64_t; /* expanded inode type */
typedef longlong_t blkcnt64_t; /* count of file blocks */
struct stat64 {
dev_t st_dev;
long st_pad1[3];
ino64_t st_ino;
mode_t st_mode;
nlink_t st_nlink;
uid_t st_uid;
gid_t st_gid;
dev_t st_rdev;
long st_pad2[2];
off64_t st_size;
timestruc_t st_atim;
timestruc_t st_mtim;
timestruc_t st_ctim;
long st_blksize;
blkcnt64_t st_blocks;
char st_fstype[_ST_FSTYPSZ];
long st_pad4[8];
};
#define O_LARGEFILE 0x2000 /* Solaris 2.6 sys/fcntl.h */
#endif /* !_LFS_LARGEFILE */
#endif /* !_JAVASOFT_SOLARIS_LARGEFILE_SUPPORT_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Interface to condition variable HPI implementation for Solaris
*/
#ifndef _JAVASOFT_CONDVAR_MD_H_
#define _JAVASOFT_CONDVAR_MD_H_
#include "threads_md.h"
typedef struct condvar {
cond_t cond; /* Manual-reset event for notifications */
unsigned int counter; /* Current number of notifications */
} condvar_t;
int condvarInit(condvar_t *);
int condvarDestroy(condvar_t *);
int condvarWait(condvar_t *, mutex_t *, thread_state_t wtype);
int condvarTimedWait(condvar_t *, mutex_t *, jlong millis, thread_state_t wtype);
int condvarSignal(condvar_t *);
int condvarBroadcast(condvar_t *);
#endif /* !_JAVASOFT_CONDVAR_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Monitor interface 10/25/94
*
* Private data structures and interfaces used in the monitor code.
* This file is used to share declarations and such between the different
* files implementing monitors. It does not contain exported API.
*/
#ifndef _JAVASOFT_SOLARIS_MONITOR_MD_H_
#define _JAVASOFT_SOLARIS_MONITOR_MD_H_
#include <mutex_md.h>
#include <condvar_md.h>
#include <threads_md.h>
/*
* Type definitions.
*/
typedef struct monitor_waiter monitor_waiter_t;
typedef struct monitor_wait_queue monitor_wait_queue_t;
/* Element of the MonitorWaitQ - representing thread doing a monitor wait */
/*
* The only reason we do the queueing is for sysMonitorDumpInfo.
* The counting, though, is used to avoid extraneous calls to
* condvarBroadcast and condvarSignal, for instance.
*/
struct monitor_waiter {
monitor_waiter_t *next;
monitor_waiter_t **prev;
sys_thread_t *waiting_thread;
};
struct monitor_wait_queue {
monitor_waiter_t *head; /* linked list of waiting threads */
short count; /* number of waiters on the list */
};
#define ANY_WAITING(mwq) ((mwq).count > 0)
#define INIT_MONITOR_WAIT_QUEUE(mwq) { (mwq).head = NULL; (mwq).count = 0; }
/* The system-level monitor data structure */
struct sys_mon {
mutex_t mutex; /* The monitor's mutex */
condvar_t cv_monitor; /* Notify those doing monitorWait on
the monitor */
/*
* Threads waiting on either of the above condvars put themselves
* on one of these lists.
*/
monitor_wait_queue_t mwait_queue; /* Head of MonitorWaitQ */
/* Thread currently executing in this monitor */
sys_thread_t *monitor_owner;
long entry_count; /* Recursion depth */
int contention_count;
};
void initializeContentionCountMutex();
typedef enum {
ASYNC_REGISTER,
ASYNC_UNREGISTER
} async_action_t;
/*
* Macros
*/
#define SYS_MID_NULL ((sys_mon_t *) 0)
typedef enum {
SYS_ASYNC_MON_ALARM = 1,
SYS_ASYNC_MON_IO,
SYS_ASYNC_MON_EVENT,
SYS_ASYNC_MON_CHILD,
SYS_ASYNC_MON_MAX
} async_mon_key_t;
#define SYS_ASYNC_MON_INPUT SYS_ASYNC_MON_IO
#define SYS_ASYNC_MON_OUTPUT SYS_ASYNC_MON_IO
sys_mon_t *asyncMon(async_mon_key_t);
#endif /* !_JAVASOFT_SOLARIS_MONITOR_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Interface to mutex HPI implementation for Solaris
*/
#ifndef _JAVASOFT_MUTEX_MD_H_
#define _JAVASOFT_MUTEX_MD_H_
#include "porting.h"
/*
* Generally, we would typedef mutex_t to be whatever the system
* supplies. But Solaris gives us mutex_t directly.
*/
#ifdef USE_PTHREADS
#define mutexInit(m) pthread_mutex_init(m, 0)
#else
#define mutexInit(m) mutex_init(m, USYNC_THREAD, 0)
#endif
#define mutexDestroy(m) mutex_destroy(m)
#define mutexLock(m) mutex_lock(m)
#define mutexUnlock(m) mutex_unlock(m)
bool_t mutexLocked(mutex_t *);
#endif /* !_JAVASOFT_MUTEX_MD_H_ */
/*
* Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Non-posix parts of the threads HPI.
*/
#ifndef _JAVASOFT_NP_H_
#define _JAVASOFT_NP_H_
extern int np_suspend(sys_thread_t *tid);
extern int np_continue(sys_thread_t *tid);
extern int np_single(void);
extern void np_multi(void);
extern int np_stackinfo(void **addr, long *size);
extern int np_initialize(void);
extern void np_initialize_thread(sys_thread_t *tid);
#ifdef __linux__
extern int np_initial_suspend(sys_thread_t *tid);
extern void np_free_thread(sys_thread_t *tid);
#endif
extern void np_profiler_init(sys_thread_t *tid);
extern int np_profiler_suspend(sys_thread_t *tid);
extern int np_profiler_continue(sys_thread_t *tid);
extern bool_t np_profiler_thread_is_running(sys_thread_t *tid);
#endif /* !_JAVASOFT_NP_H_ */
/*
* Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_PORTING_H_
#define _JAVASOFT_PORTING_H_
#ifndef USE_PTHREADS
#include <thread.h>
#include <sys/lwp.h>
#include <synch.h>
#else /* USE_PTHREADS */
#include <pthread.h>
/* There is a handshake between a newly created thread and its creator
* at thread startup because the creator thread needs to suspend the
* new thread. Currently there are two ways to do this -- with
* semaphores and with mutexes. The semaphore based implementation is
* cleaner and hence is the default. We wish the mutex based one will
* go away, but turns out the implementation of semaphores on
* Linux/ppc etc is flaky, so the mutex based solution lives for now.
*/
#ifndef USE_MUTEX_HANDSHAKE
#include <semaphore.h>
#endif
#undef BOUND_THREADS
#define thread_t pthread_t
#define mutex_t pthread_mutex_t
#define mutex_lock pthread_mutex_lock
#define mutex_trylock pthread_mutex_trylock
#define mutex_unlock pthread_mutex_unlock
#define mutex_destroy pthread_mutex_destroy
#define cond_t pthread_cond_t
#define cond_destroy pthread_cond_destroy
#define cond_wait pthread_cond_wait
#define cond_timedwait pthread_cond_timedwait
#define cond_signal pthread_cond_signal
#define cond_broadcast pthread_cond_broadcast
#define thread_key_t pthread_key_t
#define thr_setspecific pthread_setspecific
#define thr_keycreate pthread_key_create
#define thr_sigsetmask pthread_sigmask
#define thr_self pthread_self
#define thr_yield sched_yield
#define thr_kill pthread_kill
#define thr_exit pthread_exit
#ifdef __linux__
void intrHandler(void*);
#endif
#endif /* USE_PTHREADS */
#endif /* !_JAVASOFT_PORTING_H_ */
/*
* Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Implementation of the Java threads HPI on top of Solaris threads
*/
#ifndef _JAVASOFT_SOLARIS_THREADS_MD_H_
#define _JAVASOFT_SOLARIS_THREADS_MD_H_
#include "porting.h"
#ifdef sparc
#define N_TRACED_REGS 12
#elif i386
#define N_TRACED_REGS 7
#elif amd64
#define N_TRACED_REGS 15
#elif ppc
#define N_TRACED_REGS 1
#elif m68k
#define N_TRACED_REGS 8
#elif ia64
/* [RGV] I don't think this is referenced in the linux code */
#define N_TRACED_REGS 32
#else
// TODO: delete this file - threads_md.[ch] is obsolete. struct sys_thread is
// never used. Define a value just to keep compiler happy.
#define N_TRACED_REGS 32
#endif
/* Turn on if we want all java threads to be bound tolwps */
/* #define BOUND_THREADS */
/* Use /proc soln to stop lwps in place of siglwp soln */
#define PROCLWP
/*
* Thread C stack overflow check
#define sysThreadCheckStack(redzone, var) \
((var = sysThreadSelf()) && \
(unsigned int)((char *)&(var) - (char *)(var)->stack_base)\
< (redzone))
*/
/*
* Forward definition of machine dependent monitor struct
*/
struct sys_mon;
/*
* The following thread states are really hints since there is no
* interface to get at a native thread's true state. The states
* are maintained by updating the states where ever possible
* such as a transition to CONDVAR_WAIT occurs in the definition of
* the routine condvarWait().
* This state maintenance should disappear once we have a threads interface
* to obtain a thread's state.
*/
typedef enum {
FIRST_THREAD_STATE,
RUNNABLE = FIRST_THREAD_STATE,
SUSPENDED,
CONDVAR_WAIT,
NUM_THREAD_STATES
} thread_state_t;
#if defined( USE_PTHREADS) && !defined(__linux__)
/*
* Mechanism for starting a new thread suspended.
*/
typedef enum {
NEW_THREAD_MUST_REQUEST_SUSPEND,
NEW_THREAD_REQUESTED_SUSPEND,
NEW_THREAD_SUSPENDED
} new_thr_state_t;
typedef struct {
pthread_mutex_t m;
pthread_cond_t c;
new_thr_state_t state;
} new_thr_cond_t;
#endif /* USE_PTHREADS */
/*
* Machine dependent info in a sys_thread_t
*/
struct sys_thread {
/*
* Fields below this point may change on a per-architecture basis
* depending on how much work is needed to present the sysThread
* model on any given thread implementation.
*/
mutex_t mutex; /* per thread lock to protect thread fields */
thread_t sys_thread; /* The native thread id */
struct sys_thread *next; /* Pointer to next thread in the */
/* queue of all threads. */
thread_state_t state;
/* Thread status flags */
unsigned int primordial_thread:1;
unsigned int system_thread:1;
unsigned int cpending_suspend:1;
#ifdef __linux__
unsigned int pending_interrupt:1;
#endif
unsigned int interrupted:1;
unsigned int onproc:1; /* set if thread is on an LWP */
unsigned int :0;
#ifdef BOUND_THREADS
lwpid_t lwpid;
#endif
#ifdef __linux__
void *sp;
#else
unsigned long sp; /* sp at time of last (native) thread switch */
#endif
void * stack_bottom; /* The real bottom (high address) of stack */
void * stack_top; /* should be equal to stack_bottom - stack_size */
long stack_size; /* The stack size for a native thread */
long regs[N_TRACED_REGS]; /* stores registers as GC roots. */
/* Monitor specific.
Every monitor keeps track of the number of times it is
entered. When that count goes to 0, the monitor can be
freed up. But each thread has its own entry count on a
particular monitor, because multiple threads can be using a
single monitor (as one does a wait, another enters, etc.).
Each thread can only be waiting in exactly one monitor.
That monitor waited on is saved in mon_wait, and the value
of the monitor's entry_count when the wait was performed is
saved in monitor_entry_count. That is restored into the
monitor when this waiting thread is notified. */
long monitor_entry_count; /* For recursive monitor entry */
struct sys_mon *mon_wait; /* CONDVAR_WAIT'ing */
struct sys_mon *mon_enter; /* blocked waiting to enter */
void (*start_proc)(void *);
void *start_parm;
int lwp_id;
long last_sum;
struct sys_thread *prevBlocked; /* Used by nonblocking close semantics */
struct sys_thread *nextBlocked;
#ifdef USE_PTHREADS
int suspend_count;
#ifdef __linux__
sem_t sem_suspended;
sem_t sem_ready_to_suspend;
sem_t sem_selfsuspend;
int selfsuspended;
#endif
#ifdef USE_MUTEX_HANDSHAKE
new_thr_cond_t ntcond;
#else
sem_t sem;
#endif /* USE_MUTEX_HANDSHAKE */
#endif /* USE_PTHREADS */
};
#define SYS_THREAD_NULL ((sys_thread_t *) 0)
/*
* following macro copied from sys/signal.h since inside #ifdef _KERNEL there.
*/
#ifndef sigmask
#define sigmask(n) ((unsigned int)1 << (((n) - 1) & (32 - 1)))
#endif
#ifdef __linux__
extern thread_key_t intrJmpbufkey;
#else
extern thread_key_t sigusr1Jmpbufkey;
extern sigset_t sigusr1Mask;
#endif
extern sys_mon_t *_sys_queue_lock;
#define SYS_QUEUE_LOCK(self) sysMonitorEnter(self, _sys_queue_lock)
#define SYS_QUEUE_LOCKED(self) sysMonitorEntered(self, _sys_queue_lock)
#define SYS_QUEUE_UNLOCK(self) sysMonitorExit(self, _sys_queue_lock)
#define SYS_QUEUE_NOTIFYALL(self) sysMonitorNotifyAll(self, _sys_queue_lock)
#define SYS_QUEUE_WAIT(self) sysMonitorWait(self, _sys_queue_lock, \
SYS_TIMEOUT_INFINITY)
extern void setFPMode(void);
extern sys_thread_t *ThreadQueue;
extern int ActiveThreadCount; /* All threads */
#endif /* !_JAVASOFT_SOLARIS_THREADS_MD_H_ */
/*
* Copyright (c) 1994, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Condition variable HPI implementation for Solaris
*/
#include <errno.h>
#include <time.h>
#include <setjmp.h>
#include <signal.h>
#include <limits.h>
#include "hpi_impl.h"
#include "condvar_md.h"
#include "mutex_md.h"
#include "threads_md.h"
int
condvarInit(condvar_t *condvar)
{
int err;
#ifdef USE_PTHREADS
err = pthread_cond_init(&condvar->cond, NULL);
#else
err = cond_init(&condvar->cond, USYNC_THREAD, 0 /* ignored */);
#endif
condvar->counter = 0;
return (err == 0 ? SYS_OK : SYS_ERR);
}
int
condvarDestroy(condvar_t *condvar)
{
int err;
#ifdef __linux__
err = pthread_cond_destroy((cond_t *) &condvar->cond);
#else
err = cond_destroy((cond_t *) condvar);
#endif
return (err == 0 ? SYS_OK : SYS_ERR);
}
int
condvarWait(condvar_t *condvar, mutex_t *mutex, thread_state_t wtype)
{
sigjmp_buf jmpbuf;
int err;
sys_thread_t *self = sysThreadSelf();
/*
* There is no threads interface to get a thread's state. So, instead,
* we use this hack so that the debugger agent can get at this thread's
* state. Of course, this is not very reliable, but when a thread goes
* to sleep, it *will* be reported as sleeping. During the transition
* from running to sleep, it may be incorrectly reported, since the
* setting of the state here is not atomic with the voluntary sleep.
* The better fix is to extend the Solaris threads interface and have
* the debugger agent call this interface OR to use libthread_db for
* intra-process state reporting.
*
* Now, condition variables are used either for waiting to enter a
* monitor (MONITOR_WAIT) or to execute a "wait()" method when already
* holding a monitor (CONDVAR_WAIT). So, when condvarWait() is called
* it could be to wait for a monitor or for a condition within a
* monitor. This is indicated by the "wtype" argument to condvarWait().
* This type is set in the thread state before going to sleep.
*/
self->state = wtype;
#ifdef __linux__
/*
* Register our intrHandler as a cleanup handler. If we get
* interrupted (i.e. canceled), we longjmp out of this handler.
*/
pthread_cleanup_push(intrHandler, NULL);
if (setjmp(jmpbuf) == 0) {
/*
* Set the jmp buf and enable cancellation.
*/
thr_setspecific(intrJmpbufkey, &jmpbuf);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/*
* Note: pthread_cond_wait is _not_ interruptible on Linux
*/
#else
thr_setspecific(sigusr1Jmpbufkey, &jmpbuf);
if (sigsetjmp(jmpbuf, 1) == 0) {
sigset_t osigset;
thr_sigsetmask(SIG_UNBLOCK, &sigusr1Mask, &osigset);
again:
#endif
err = cond_wait((cond_t *) condvar, (mutex_t *) mutex);
switch(err) {
case 0:
err = SYS_OK;
break;
#ifndef __linux__
case EINTR: /* Signals other than USR1 were received. */
goto again;
#endif
default:
err = SYS_ERR;
}
#ifdef __linux__
/*
* Disable cancellation and clear the jump buf.
*/
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
thr_setspecific(intrJmpbufkey, NULL);
#else
thr_sigsetmask(SIG_SETMASK, &osigset, NULL);
#endif
} else {
/*
* we've received a SIGUSR1 to interrupt our wait. We just return
* and something above use notices the change.
* clear the jump buf just to be paranoid.
*/
#ifndef __linux__
thr_setspecific(sigusr1Jmpbufkey, NULL);
#endif
err = SYS_INTRPT;
}
#ifdef __linux__
pthread_cleanup_pop(0);
#endif
/*
* After having woken up, change the thread state to RUNNABLE, since
* it is now runnable.
*/
self->state = RUNNABLE;
return err;
}
/*
* Returns 0 if condition variable became true before timeout expired.
* Returns 1 if timeout expired first.
* Returns <0 if wait fails for any other reason.
*/
int
condvarTimedWait(condvar_t *condvar, mutex_t *mutex,
jlong millis, thread_state_t wtype)
{
#ifdef __linux__
jmp_buf jmpbuf;
#else
sigjmp_buf jmpbuf;
#endif
int err;
struct timespec timeout;
sys_thread_t *self;
jlong end_time;
if (millis < 0)
return SYS_ERR;
if (millis > (jlong)INT_MAX) {
return condvarWait(condvar, mutex, wtype);
}
end_time = sysTimeMillis() + millis;
self = sysThreadSelf();
self->state = wtype;
#ifdef __linux__
/*
* Register our intrHandler as a cleanup handler. If we get
* interrupted (i.e. canceled), we longjmp out of this handler.
*/
pthread_cleanup_push(intrHandler, NULL);
if (setjmp(jmpbuf) == 0) {
/*
* Set the jmp buf and enable cancellation.
*/
thr_setspecific(intrJmpbufkey, &jmpbuf);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/*
* Calculate an absolute timeout value.
*/
timeout.tv_sec = end_time / 1000;
timeout.tv_nsec = (end_time % 1000) * 1000000;
again:
#else
thr_setspecific(sigusr1Jmpbufkey, &jmpbuf);
if (sigsetjmp(jmpbuf, 1) == 0) {
sigset_t osigset;
thr_sigsetmask(SIG_UNBLOCK, &sigusr1Mask, &osigset);
again:
timeout.tv_sec = end_time / 1000;
timeout.tv_nsec = (end_time % 1000) * 1000000;
#endif
err = cond_timedwait((cond_t *)condvar, (mutex_t *)mutex, &timeout);
switch(err) {
case 0:
err = SYS_OK;
break;
case EINTR: /* Signals other than USR1 were received. */
if (sysTimeMillis() < end_time) {
goto again;
}
/*FALLTHRU*/
#ifdef USE_PTHREADS
case ETIMEDOUT:
#else
case ETIME:
#endif
err = SYS_TIMEOUT;
break;
default:
err = SYS_ERR;
}
#ifdef __linux__
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
thr_setspecific(intrJmpbufkey, NULL);
#else
thr_sigsetmask(SIG_SETMASK, &osigset, NULL);
#endif
} else {
/*
* we've received a SIGUSR1 to interrupt our wait. We just return
* and something above use notices the change.
* clear the jump buf just to be paranoid.
*/
#ifndef __linux__
thr_setspecific(sigusr1Jmpbufkey, NULL);
#endif
err = SYS_INTRPT;
}
#ifdef __linux__
/* Remove intrHandler without calling it. */
pthread_cleanup_pop(0);
sysAssert(pthread_mutex_trylock(mutex) == EBUSY);
/*
* After having woken up, change the thread state to RUNNABLE, since
* it is now runnable.
*/
#endif
self->state = RUNNABLE;
return err;
}
int
condvarSignal(condvar_t *condvar)
{
int err;
err = cond_signal((cond_t *) condvar);
condvar->counter++;
return (err == 0 ? SYS_OK : SYS_ERR);
}
int
condvarBroadcast(condvar_t *condvar)
{
int err;
err = cond_broadcast((cond_t *) condvar);
condvar->counter++;
return (err == 0 ? SYS_OK : SYS_ERR);
}
/*
* Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Solaris 2.X dependant interrupt handling code.
*/
/*
* Header files.
*/
#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include "hpi_impl.h"
#include "mutex_md.h"
#include "condvar_md.h"
#include "monitor_md.h"
#include "threads_md.h"
#include "interrupt.h"
static int pending_signals[N_INTERRUPTS];
/* Stubs used from interrupt.c: they are nontrivial on Green */
void intrLock() {}
void intrUnlock() {}
#ifdef __linux__
extern int sr_sigsusp;
extern int sr_sigresu;
#endif
/* We need a special monitor implementation for signals because
* signal handlers are not necessarily called in a Java thread.
*/
struct {
thread_t owner;
unsigned int count;
mutex_t mutex;
condvar_t condvar;
} userSigMon;
static void sigMonitorInit()
{
userSigMon.owner = 0;
userSigMon.count = 0;
mutexInit(&userSigMon.mutex);
condvarInit(&userSigMon.condvar);
}
static void sigMonitorEnter()
{
thread_t self = thr_self();
if (userSigMon.owner == self) {
userSigMon.count++;
} else {
mutex_lock(&userSigMon.mutex);
userSigMon.owner = self;
userSigMon.count = 1;
}
}
static void sigMonitorExit()
{
thread_t self = thr_self();
sysAssert(userSigMon.owner == self);
sysAssert(userSigMon.count > 0);
if (--userSigMon.count == 0) {
userSigMon.owner = 0;
mutex_unlock(&userSigMon.mutex);
}
}
static void sigMonitorNotify()
{
thread_t self = thr_self();
sysAssert(userSigMon.owner == self);
sysAssert(userSigMon.count > 0);
condvarSignal(&userSigMon.condvar);
}
static void sigMonitorWait()
{
thread_t self = thr_self();
unsigned int saved_count = userSigMon.count;
sysAssert(userSigMon.owner == self);
sysAssert(userSigMon.count > 0);
userSigMon.count = 0;
userSigMon.owner = 0;
condvarWait(&userSigMon.condvar, &userSigMon.mutex, CONDVAR_WAIT);
sysAssert(userSigMon.owner == 0);
sysAssert(userSigMon.count == 0);
userSigMon.count = saved_count;
userSigMon.owner = self;
}
static int
my_sigignore(int sig)
{
#ifndef HAVE_SIGIGNORE
struct sigaction action;
sigset_t set;
action.sa_handler = SIG_IGN;
action.sa_flags = 0;
sigemptyset(&action.sa_mask);
if (sigaction(sig, &action, (struct sigaction *)0) < 0)
return -1;
sigemptyset(&set);
if (sigaddset(&set, sig) < 0)
return -1;
return sigprocmask(SIG_UNBLOCK, &set, (sigset_t *)0);
#else
return sigignore(sig);
#endif /* HAVE_SIGIGNORE */
}
/*
* intrInitMD() -- Target-specific initialization.
*/
extern void
intrInitMD()
{
memset(pending_signals, 0, sizeof(pending_signals));
(void)my_sigignore(SIGPIPE);
sigMonitorInit();
}
/*-
* intrDispatchMD() -- Turn our signal into an intrDispatch().
*/
void
#ifdef SA_SIGINFO
intrDispatchMD(int sig, siginfo_t *info, void *uc)
#else
intrDispatchMD(int sig)
#endif /* SA_SIGINFO */
{
Log1(1, "signalHandlerDispatch(sig=%d)\n", sig);
sigMonitorEnter();
#ifdef SA_SIGINFO
#if defined(__linux__) && defined(__sparc__)
uc = (((char *)&sig) + 4 + 0x20);
info = (siginfo_t *)(((char *)uc) + 0x60);
#endif
intrDispatch(sig, info, uc);
#else
intrDispatch(sig, 0, 0);
#endif /* SA_SIGINFO */
sigMonitorExit();
}
bool_t intrInUse(int sig)
{
/* Signals used in native threads implementation. */
#ifdef __linux__
return sig == SIGPIPE || sig == sr_sigsusp || sig == sr_sigresu;
#else
return sig == SIGPIPE || sig == SIGUSR1;
#endif
}
void sysSignalNotify(int sig)
{
sigMonitorEnter();
pending_signals[sig]++;
sigMonitorNotify();
sigMonitorExit();
}
static int lookupSignal()
{
int i;
for (i = 0; i < N_INTERRUPTS; i++) {
if (pending_signals[i]) {
pending_signals[i]--;
return i;
}
}
return -1;
}
int sysSignalWait()
{
int sig;
sigMonitorEnter();
while ((sig = lookupSignal()) == -1) {
sigMonitorWait();
}
sigMonitorExit();
return sig;
}
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Monitor implementation for Native Solaris threads
*
* Java Monitors are implemented using one solaris mutex and two
* condition variables. Because solaris mutex is not re-entrant we
* cannot simply have a monitor map to a mutex as re-entering a monitor
* would deadlock an application.
*
* Monitor is implemented using:
* mutex_t mutex;
* condvar_t cv_monitor;
* condvar_t cv_waiters;
*
* mutex protects the monitor state.
* cv_monitor is the condtion variable used along with mutex for
* supporting wait and notify on the monitor.
* cv_waiters is used for all the threads waiting to acquire the monitor
* lock.
*
* All of the sysMonitorXXX() functions that are passed a sys_mon_t
* assume that they get something nonnull, and only check when debugging.
*/
#include "hpi_impl.h"
#include "threads_md.h"
#include "monitor_md.h"
#include <errno.h>
#include <limits.h>
static mutex_t contention_count_mutex;
void initializeContentionCountMutex()
{
mutexInit(&contention_count_mutex);
}
/*
* Operations on monitors
*/
/*
* Return the size of the lib-dependent portion of monitors. This
* is done this way so that monitors can be all of one piece,
* without paying the penalty of an extra level of indirection on
* each sys_mon reference. This is not how it is done for threads
* and it might be a good idea to use a pointer the same way that
* threads do.
*/
size_t
sysMonitorSizeof()
{
return sizeof(struct sys_mon);
}
int
sysMonitorInit(sys_mon_t *mid)
{
int ret;
sysAssert(mid != SYS_MID_NULL);
ret = mutexInit(&mid->mutex);
ret = (ret == SYS_OK ? condvarInit(&mid->cv_monitor) : ret);
mid->entry_count = 0;
mid->monitor_owner = SYS_THREAD_NULL;
mid->contention_count = 0;
INIT_MONITOR_WAIT_QUEUE( mid->mwait_queue );
return ret;
}
/*
* Free any system-dependent resources held by monitors. There is
* nothing to be done for native Solaris mutexes or condition variables.
*/
int
sysMonitorDestroy(sys_mon_t *mid)
{
sysAssert(mid != SYS_MID_NULL);
return SYS_OK;
}
static void
enqueue_me(monitor_waiter_t *mp, monitor_wait_queue_t *queue,
sys_thread_t *self)
{
/*
* Order does not matter here. It is more convenient to
* enqueue ourselves at the head of the list, so we do so.
*/
mp->waiting_thread = self;
mp->next = queue->head;
mp->prev = &(queue->head);
if ( queue->head != NULL ){
queue->head->prev = &(mp->next);
}
queue->head = mp;
queue->count++;
}
static void
dequeue_me(monitor_waiter_t *mp, monitor_wait_queue_t *queue)
{
queue->count--;
*(mp->prev) = mp->next;
if (mp->next != NULL ){
mp->next->prev = mp->prev;
}
mp->next = NULL;
}
int
sysMonitorEnter(sys_thread_t *self, sys_mon_t *mid)
{
int err;
sysAssert(mid != SYS_MID_NULL);
err = mutex_trylock(&mid->mutex);
if (err == 0) { /* no one owns it */
mid->monitor_owner = self;
mid->entry_count = 1;
return SYS_OK;
} else if (err == EBUSY) { /* it's already locked */
if (mid->monitor_owner == self) {
mid->entry_count++;
return SYS_OK;
} else {
self->mon_enter = mid;
/* block on it */
if (profiler_on) {
VM_CALL(monitorContendedEnter)(self, mid);
mutexLock(&contention_count_mutex);
mid->contention_count++;
mutexUnlock(&contention_count_mutex);
}
mutex_lock(&mid->mutex);
mid->monitor_owner = self;
mid->entry_count = 1;
self->mon_enter = NULL;
if (profiler_on) {
mutexLock(&contention_count_mutex);
mid->contention_count--;
mutexUnlock(&contention_count_mutex);
VM_CALL(monitorContendedEntered)(self, mid);
}
return SYS_OK;
}
} else {
sysAssert(err == 0);
return SYS_ERR;
}
}
/*
* Return true if we currently own this monitor (and threads have been
* initialized.
*/
bool_t
sysMonitorEntered(sys_thread_t *self, sys_mon_t *mid)
{
sysAssert(mid != SYS_MID_NULL);
/* We can only have locked monitors if threads have been initialized */
return (mid->monitor_owner == self);
}
int
sysMonitorExit(sys_thread_t *self, sys_mon_t *mid)
{
sysAssert(mid != SYS_MID_NULL);
if (mid->monitor_owner == self) {
sysAssert(mid->entry_count > 0);
if (--mid->entry_count == 0) {
mid->monitor_owner = SYS_THREAD_NULL;
if (!mid->contention_count || !profiler_on) {
mutex_unlock(&mid->mutex);
} else {
mutex_unlock(&mid->mutex);
VM_CALL(monitorContendedExit)(self, mid);
}
}
return SYS_OK;
} else {
return SYS_ERR;
}
}
int
sysMonitorNotify(sys_thread_t *self, sys_mon_t *mid)
{
sysAssert(mid != SYS_MID_NULL);
if (self == mid->monitor_owner) {
if (ANY_WAITING(mid->mwait_queue)) {
/* If there is someone doing a monitor wait */
condvarSignal(&(mid->cv_monitor));
}
return SYS_OK;
} else
return SYS_ERR;
}
int
sysMonitorNotifyAll(sys_thread_t *self, sys_mon_t *mid)
{
sysAssert(mid != SYS_MID_NULL);
if (self == mid->monitor_owner) {
if (ANY_WAITING(mid->mwait_queue)) {
/* If there is someone doing a monitor wait */
condvarBroadcast(&(mid->cv_monitor));
}
return SYS_OK;
} else
return SYS_ERR;
}
int
sysMonitorWait(sys_thread_t *self, sys_mon_t *mid, jlong millis)
{
int ret = SYS_OK;
monitor_waiter_t me;
sysAssert(mid != SYS_MID_NULL);
if (self != mid->monitor_owner) {
return SYS_ERR;
}
if (sysThreadIsInterrupted(self, TRUE)) {
return SYS_INTRPT;
}
/* Prepare to wait: drop mutex ownership */
sysAssert(self->monitor_entry_count == 0);
sysAssert(self->mon_wait == 0);
self->mon_wait = (sys_mon_t *) mid;
self->monitor_entry_count = mid->entry_count;
mid->entry_count = 0;
mid->monitor_owner = SYS_THREAD_NULL;
/* Add myself to the monitor waitq */
enqueue_me(&me, &mid->mwait_queue, self);
if (millis == SYS_TIMEOUT_INFINITY) {
ret = condvarWait(&mid->cv_monitor, &mid->mutex, CONDVAR_WAIT);
} else {
ret = condvarTimedWait(&mid->cv_monitor, &mid->mutex, millis,
CONDVAR_WAIT);
}
dequeue_me(&me, &mid->mwait_queue);
sysAssert(mid->monitor_owner == NULL);
sysAssert(mid->entry_count == 0);
mid->monitor_owner = self;
mid->entry_count = self->monitor_entry_count;
self->monitor_entry_count = 0;
self->mon_wait = 0;
/* Did we get interrupted in mid-wait? (IS THIS THE RIGHT PLACE?) */
if (sysThreadIsInterrupted(self, TRUE)) {
return SYS_INTRPT;
}
return ret;
}
static int
dumpWaitingQueue(monitor_wait_queue_t *queue, sys_thread_t **waiters, int sz)
{
int n;
monitor_waiter_t * waiter;
if (queue == NULL || ( waiter = queue->head ) == NULL ) {
return 0;
}
for (n = 0; waiter != 0; waiter = waiter->next, n++, sz--) {
if (sz > 0) {
waiters[n] = waiter->waiting_thread;
}
}
return n;
}
typedef struct {
sys_mon_t *mid;
sys_thread_t **waiters;
int sz;
int nwaiters;
} wait_info;
static int
findWaitersHelper(sys_thread_t *t, void *arg)
{
wait_info * winfo = (wait_info *) arg;
if (t->mon_enter == winfo->mid) {
if (winfo->sz > 0) {
winfo->waiters[winfo->nwaiters] = t;
}
winfo->sz--;
winfo->nwaiters++;
}
return SYS_OK;
}
int
sysMonitorGetInfo(sys_mon_t *mid, sys_mon_info *info)
{
wait_info winfo;
sysAssert(mid != SYS_MID_NULL);
info->owner = mid->monitor_owner;
if (mid->monitor_owner) {
info->entry_count = mid->entry_count;
}
winfo.mid = mid;
winfo.nwaiters = 0;
winfo.waiters = info->monitor_waiters;
winfo.sz = info->sz_monitor_waiters;
sysThreadEnumerateOver(findWaitersHelper, (void *) &winfo);
info->n_monitor_waiters = winfo.nwaiters;
info->n_condvar_waiters = dumpWaitingQueue(&mid->mwait_queue,
info->condvar_waiters,
info->sz_condvar_waiters);
return SYS_OK;
}
bool_t
sysMonitorInUse(sys_mon_t * mon)
{
return mon->monitor_owner != 0 ||
mon->mwait_queue.count != 0;
}
sys_thread_t *
sysMonitorOwner(sys_mon_t *mon)
{
return mon->monitor_owner;
}
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Mutex HPI implementation for Solaris
*
* Mutexes are used both by the system-independent monitor implementation and
* to implement critical regions elsewhere within the runtime.
*/
#include <errno.h>
#include "hpi_impl.h"
#include "mutex_md.h"
#include "threads_md.h"
/*
* Return true of the mutex in question is already locked. note:
* this does not tell if the mutex is already locked by *this*
* thread, only that is is locked by *some* thread.
*/
bool_t
mutexLocked(mutex_t *mutex)
{
if (mutex_trylock(mutex) == 0) {
mutex_unlock(mutex);
return FALSE;
}
return TRUE;
}
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Solaris-dependent I/O Note: Routines here are just place holders -
* eventually we need to put in a solution that involves using
* setjmp/longjmp to avoid io races. Look at green_threads/io_md.c for
* more detailed comments on the architechture of the io modules.
*/
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef HAVE_FILIOH
#include <sys/filio.h>
#else
#include <sys/ioctl.h>
#endif
#include <sys/socket.h>
#include <setjmp.h>
#include <signal.h>
#ifndef USE_SELECT
#include <poll.h>
#endif
#include "hpi_impl.h"
#include "threads_md.h"
#include "io_md.h"
#include "largefile.h"
#include "mutex_md.h"
#if defined(__solaris__) && defined(NO_INTERRUPTIBLE_IO)
#error If there was no policy change, this could be a makefile error.
#endif
#ifdef NO_INTERRUPTIBLE_IO
#undef CLOSEIO
#else
#define CLOSEIO
#endif /* NO_INTERRUPTIBLE_IO */
/* Get typedef for rlim_t */
#include <sys/resource.h>
#ifdef CLOSEIO
/*
* Structure for file control block, used by closable IO.
* We should NOT add more field into the data structure.
* Otherwise, the sysRead() will only work with sysOpen,
* and may NOT work with a fd return by open()
*/
typedef struct
{
mutex_t lock; /* lock against the entry */
sys_thread_t* list; /* blocking list on the fd */
} file_t;
/*
* Global data structure for interruptable io.
* It must be initialized before any IO access.
*/
static file_t * fd_table = 0;
static int fd_limit = 0;
/*
* Initialize global data structure for non-blocking
* close semantics for Solaris 2.6 and ealier.
*/
int InitializeIO(rlim_t limit)
{
int i;
fd_limit = (int) limit;
fd_table = (file_t *) sysCalloc(fd_limit, sizeof(file_t));
if (fd_table == 0) {
return SYS_ERR;
}
for (i = 0; i < fd_limit; i++) {
mutexInit(&(fd_table[i].lock));
}
return SYS_OK;
}
/*
* Cleanup the data structure allocated as above.
* For JDK 1.2, this function is not called ...
*/
void FinalizeIO() {
int i;
for (i = 0; i < fd_limit; i++) {
mutexDestroy(&fd_table[i].lock);
}
sysFree(fd_table);
fd_table = 0;
}
/*
* Non-blocking close semantics on Solaris native thread.
*/
int sysClose(int fd)
{
int ret;
/* Check if it is valid fd. */
if (fd >= 0 && fd < fd_limit) {
file_t* file = &fd_table[fd];
sys_thread_t *thread;
sys_thread_t *next;
/* Lock the corresponding fd. */
mutexLock(&file->lock);
/* Read the blocking list. */
thread = file->list;
/* Iterates the list and interrupt every thread in there. */
while (thread) {
/* This is the classic double-linked list operation. */
if (thread->nextBlocked != thread) {
next = thread->nextBlocked;
next->prevBlocked = thread->prevBlocked;
thread->prevBlocked->nextBlocked = next;
} else {
next = 0;
}
thread->nextBlocked = 0;
thread->prevBlocked = 0;
/*
* Use current interruptable IO mechanism to
* implement non-blocking closable IO.
*/
sysThreadInterrupt(thread);
thread = next;
}
file->list = 0;
ret = close(fd);
mutexUnlock(&file->lock);
} else {
/* It is not a valid fd. */
errno = EBADF;
ret = SYS_ERR;
}
return ret;
}
/*
* Called before entering blocking IO. Enqueue the current
* thread to the fd blocking list. Need fd lock.
*/
static void BeginIO(sys_thread_t* self, file_t* file) {
mutexLock(&file->lock);
if (!file->list) {
file->list = self->nextBlocked = self->prevBlocked = self;
} else {
sys_thread_t* head = file->list;
self->prevBlocked = head->prevBlocked;
self->nextBlocked = head;
head->prevBlocked->nextBlocked = self;
head->prevBlocked = self;
}
mutexUnlock(&file->lock);
}
/*
* Called after finishing blocking IO. Dequeue the current
* thread from the blocking list. Note: It may be waken up
* by thread interrupt or fd close operation.
*/
static ssize_t EndIO(sys_thread_t* self, file_t* file, ssize_t ret) {
mutexLock(&file->lock);
/*
* Dequeue the current thread. It is classic double
* linked list operation.
*/
#ifdef __linux__
if (!sysThreadIsInterrupted(self, 1) && self->prevBlocked) {
#else
if (self->prevBlocked) {
#endif
if (self->nextBlocked != self) {
self->prevBlocked->nextBlocked = self->nextBlocked;
self->nextBlocked->prevBlocked = self->prevBlocked;
file->list = self->nextBlocked;
} else {
file->list = 0;
}
self->nextBlocked = 0;
self->prevBlocked = 0;
} else {
#ifdef __linux__
if (self->nextBlocked && self->prevBlocked) {
if (self->nextBlocked != self) {
self->prevBlocked->nextBlocked = self->nextBlocked;
self->nextBlocked->prevBlocked = self->prevBlocked;
file->list = self->nextBlocked;
} else {
file->list = 0;
}
}
self->nextBlocked = 0;
self->prevBlocked = 0;
#endif
/* file got closed during blocking call */
errno = EBADF;
ret = SYS_ERR;
}
mutexUnlock(&file->lock);
return ret;
}
/*
* The following is a big macro used to implement the closable IO.
* Note: It is also used by interruptable IO. If later we need to
* deprecate interruptable IO, all we need to change the return
* value and errno to EBADF instead of EINTR. The high level
* routine will interpret it as IOException instead of
* InterruptedIOException. No other change is needed.
* The underlying mechanism is using the SIGUSR1 signal to wake up the
* blocking thread. This may cause severe conflicts with any other
* libraries that also use SIGUSR1.
*/
#ifdef __linux__
#define INTERRUPT_IO(cmd) \
{\
ssize_t ret = 0;\
file_t* file;\
sys_thread_t* self = sysThreadSelf();\
\
if (fd < 0 || fd >= fd_limit) {\
errno = EBADF;\
return SYS_ERR;\
}\
\
file = &fd_table[fd];\
BeginIO(self, file);\
\
{\
jmp_buf jmpbuf;\
\
/*\
* Register our intrHandler as a cleanup handler. If we get\
* interrupted (i.e. canceled), we longjmp out of this handler.\
*/\
pthread_cleanup_push(intrHandler, NULL);\
if (setjmp(jmpbuf) == 0) {\
thr_setspecific(intrJmpbufkey, &jmpbuf);\
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);\
ret = cmd;\
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);\
thr_setspecific(intrJmpbufkey, NULL);\
} else {\
/* [jk] should/can we call sysThreadIsInterrupted(self, 1) here */
self->interrupted = FALSE;\
errno = EINTR;\
ret = SYS_INTRPT;\
}\
/* Remove intrHandler without calling it. */\
pthread_cleanup_pop(0);\
}\
\
return EndIO(self, file, ret);\
}
#else
#define INTERRUPT_IO(cmd) \
{\
int ret = 0;\
file_t* file;\
sys_thread_t* self = sysThreadSelf();\
\
if (fd < 0 || fd >= fd_limit) {\
errno = EBADF;\
return SYS_ERR;\
}\
\
file = &fd_table[fd];\
BeginIO(self, file);\
\
{\
sigjmp_buf jmpbuf;\
sigset_t omask;\
\
thr_setspecific(sigusr1Jmpbufkey, &jmpbuf);\
if (sigsetjmp(jmpbuf, 1) == 0) {\
thr_sigsetmask(SIG_UNBLOCK, &sigusr1Mask, &omask);\
ret = cmd;\
thr_sigsetmask(SIG_SETMASK, &omask, NULL);\
} else {\
sysThreadIsInterrupted(self, TRUE);\
errno = EINTR;\
ret = SYS_INTRPT;\
}\
}\
\
return EndIO(self, file, ret);\
}
#endif
#else /* CLOSEIO */
#define INTERRUPT_IO(cmd) \
return cmd;
int sysClose(int fd) {
return close(fd);
}
int InitializeIO(rlim_t limit)
{
return SYS_OK;
}
#endif /* CLOSEIO */
/*
* sys API for I/O
*/
size_t
sysRead(int fd, void *buf, unsigned int nBytes) {
INTERRUPT_IO(read(fd, buf, nBytes))
}
size_t
sysWrite(int fd, const void *buf, unsigned int nBytes) {
INTERRUPT_IO(write(fd, buf, nBytes))
}
int
sysSocket(int domain, int type, int protocol) {
return socket(domain, type, protocol);
}
ssize_t
sysRecv(int fd, char *buf, int nBytes, int flags) {
INTERRUPT_IO(recv(fd, buf, nBytes, flags))
}
ssize_t
sysSend(int fd, char *buf, int nBytes, int flags) {
INTERRUPT_IO(send(fd, buf, nBytes, flags))
}
/*
int
sysClose(int fd) {
INTERRUPT_IO(close(fd))
}
*/
jlong
sysSeek(int fd, jlong offset, int whence) {
return lseek64_w(fd, offset, whence);
}
int
sysSetLength(int fd, jlong length) {
return ftruncate64_w(fd, length);
}
int
sysSync(int fd) {
/*
* XXX: Is fsync() interruptible by the interrupt method?
* Is so, add the TSD, sigsetjmp()/longjmp() code here.
*
* This probably shouldn't be throwing an error and should
* be a macro.
*/
int ret;
if ((ret = fsync(fd)) == -1) {
}
return ret;
}
int
sysAvailable(int fd, jlong *pbytes) {
jlong cur, end;
int mode;
if (sysFfileMode(fd, &mode) >= 0) {
if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
/*
* XXX: is the following call interruptible? If so, this might
* need to go through the INTERRUPT_IO() wrapper as for other
* blocking, interruptible calls in this file.
*/
int n;
if (ioctl(fd, FIONREAD, &n) >= 0) {
*pbytes = n;
return 1;
}
}
}
if ((cur = lseek64_w(fd, 0L, SEEK_CUR)) == -1) {
return 0;
} else if ((end = lseek64_w(fd, 0L, SEEK_END)) == -1) {
return 0;
} else if (lseek64_w(fd, cur, SEEK_SET) == -1) {
return 0;
}
*pbytes = end - cur;
return 1;
}
/* IO routines that take in a FD object */
int
sysTimeout(int fd, long timeout) {
#ifndef USE_SELECT
struct pollfd pfd;
#ifdef __linux__
jlong end_time = sysTimeMillis() + (jlong) timeout;
volatile jlong to = (jlong) timeout;
#endif
pfd.fd = fd;
pfd.events = POLLIN;
#ifdef __linux__
INTERRUPT_IO(__extension__ ({
int __result;
do {
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
__result = poll(&pfd, 1, ((int)to));
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
} while (__result == -1 && errno == EINTR &&
(to = end_time - sysTimeMillis()) > 0 &&
((pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) == 0));
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
__result = -1;
errno = EBADF;
}
(__result == -1 && errno == EINTR) ? 0 : __result;
}))
#else
INTERRUPT_IO(poll(&pfd, 1, (int)timeout))
#endif
#else
fd_set tbl;
struct timeval t;
t.tv_sec = timeout / 1000;
t.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&tbl);
FD_SET(fd, &tbl);
#ifdef __linux__
INTERRUPT_IO(TEMP_FAILURE_RETRY(select(fd + 1, &tbl, 0, 0, &t)))
#else
INTERRUPT_IO(select(fd + 1, &tbl, 0, 0, &t))
#endif
#endif
}
/*
* sys API for networking
*/
long
sysSocketAvailable(int fd, jint *pbytes) {
long ret = 1;
/*
* An ILP64 port of this code should pass the address of a local int
* to the ioctl and then convert that to jint with any error handling
* required for overflows, if overflow is possible.
*/
/*
* XXX: is the following call interruptible? If so, this might
* need to go through the INTERRUPT_IO() wrapper as for other
* blocking, interruptible calls in this file.
*/
if (fd < 0 || ioctl(fd, FIONREAD, pbytes) < 0) {
ret = 0;
}
return ret;
}
int
sysListen(int fd, int count) {
return listen(fd, count);
}
int
sysConnect(int fd, struct sockaddr *addr, int size) {
INTERRUPT_IO(connect(fd, addr, size))
}
int
sysBind(int fd, struct sockaddr *addr, int size) {
INTERRUPT_IO(bind(fd, addr, size))
}
int
sysAccept(int fd, struct sockaddr *him, int *len) {
INTERRUPT_IO(accept(fd, him, (uint *)len))
}
int
sysGetSockName(int fd, struct sockaddr *him, int *len) {
return getsockname(fd, him, (uint *)len);
}
int
sysSocketClose(int fd) {
return sysClose(fd);
}
int
sysSocketShutdown(int fd, int howto) {
return shutdown(fd, howto);
}
int
sysGetSockOpt(int fd, int level, int optname, char *optval, int *optlen) {
return getsockopt(fd, level, optname, optval, optlen);
}
int
sysSetSockOpt(int fd, int level, int optname, const char *optval, int optlen) {
return setsockopt(fd, level, optname, optval, optlen);
}
int
sysGetHostName(char *hostname, int namelen) {
return gethostname(hostname, namelen);
}
struct hostent *
sysGetHostByAddr(const char *hostname, int len, int type) {
return gethostbyaddr(hostname, len, type);
}
struct hostent *
sysGetHostByName(char *hostname) {
return gethostbyname(hostname);
}
struct protoent *
sysGetProtoByName(char* name) {
return getprotobyname(name);
}
/*
* Routines to do datagrams
*/
ssize_t
sysSendTo(int fd, char *buf, int len,
int flags, struct sockaddr *to, int tolen) {
INTERRUPT_IO(sendto(fd, buf, len, flags, to, tolen))
}
ssize_t
sysRecvFrom(int fd, char *buf, int nBytes,
int flags, struct sockaddr *from, int *fromlen) {
INTERRUPT_IO(recvfrom(fd, buf, nBytes, flags, from, (uint *)fromlen))
}
/*
* Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Implementation of notposix.h on Linux.
*/
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include "hpi_impl.h"
#include "monitor_md.h"
#include "threads_md.h"
#include "np.h"
#undef LOG_THREADS
/* Global lock used when calling np_suspend and np_resume */
static pthread_mutex_t sr_lock;
/* Semaphore used to acknowledge when the handler has received HANDLER_SIG */
static sem_t sr_sem;
/* The tid of the thread being suspended/resumed */
static sys_thread_t *sr_tid;
int sr_sigsusp;
int sr_sigresu;
static void prtsigset(char *s, sigset_t *set)
{
int sig;
dprintf(2, "%s:", s);
for (sig = 1; sig < _NSIG; sig++) {
if (sigismember(set, sig)) {
dprintf(2, " %d", sig);
}
}
dprintf(2, "\n");
}
/*
* Handler function invoked when a thread's execution is suspended
* We have to be careful that only async-safe functions are
* called here. I'm not even sure if calling sysThreadSelf is safe so
* we temporarily stash SP in a global variable instead.
*/
static void
#ifdef SA_SIGINFO
susp_handler(int sig, siginfo_t* info, void* arg)
#else
susp_handler(int sig)
#endif
{
sys_thread_t *tid = sr_tid;
sigset_t set;
/* Save the current SP */
tid->sp = &tid;
sem_post(&sr_sem);
sigfillset(&set);
sigdelset(&set,(sr_sigresu));
/* block until we receive resume signal. */
sigsuspend(&set);
}
static void
#ifdef SA_SIGINFO
resu_handler(int sig, siginfo_t* info, void* arg)
#else
resu_handler(int sig)
#endif
{
return;
}
/*
* Initialize signal handlers for suspend and resume}.
*/
int
np_initialize()
{
struct sigaction act;
char *s;
int err;
/* Signal numbers used to suspend and resume */
#if __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
#ifdef SIGUNUSED
sr_sigsusp = SIGUNUSED;
#else
sr_sigsusp = SIGLOST;
#endif
#ifdef SIGPWR
sr_sigresu = SIGPWR;
#else
sr_sigresu = SIGXFSZ;
#endif
#else
/* use real time signals */
/* currently __SIGRTMIN, +1, +2 are all used by LinuxThreads */
sr_sigsusp = SIGRTMIN + 3;
sr_sigresu = SIGRTMIN + 4;
#endif
/* Set up signal handler for suspend and resume */
#if defined(SA_SIGINFO) && !defined(__sparc__)
act.sa_handler = 0;
act.sa_sigaction = susp_handler;
#else
act.sa_handler = (__sighandler_t) susp_handler;
#endif
#ifdef SA_SIGINFO
act.sa_flags = SA_RESTART | SA_SIGINFO;
#else
act.sa_flags = SA_RESTART;
#endif
sigfillset(&act.sa_mask);
if (sigaction(sr_sigsusp, &act, 0) == -1) {
return -1;
}
#if defined(SA_SIGINFO) && !defined(__sparc__)
act.sa_handler = 0;
act.sa_sigaction = resu_handler;
#else
act.sa_handler = (__sighandler_t) resu_handler;
#endif
#ifdef SA_SIGINFO
act.sa_flags = SA_SIGINFO;
#else
act.sa_flags = 0;
#endif
sigfillset(&act.sa_mask);
if (sigaction(sr_sigresu, &act, 0) == -1) {
return -1;
}
/* Initialize semaphore used by np_{suspend/resume} */
if (sem_init(&sr_sem, 0, 0) == -1) {
return SYS_ERR;
}
/* Initialize mutex used by np_{suspend/resume} */
err = mutexInit(&sr_lock);
sysAssert(err == 0);
return SYS_OK;
}
int
np_initial_suspend(sys_thread_t* tid)
{
int count;
tid->selfsuspended = (tid == sysThreadSelf());
sysAssert(tid->selfsuspended);
count = tid->suspend_count++;
sysAssert(count == 0);
#ifdef LOG_THREADS
dprintf(2,
"[Initial self-suspend [tid = %ld, sys_thread = %ld]\n",
pthread_self(), tid->sys_thread);
#endif
/* Order should not matter but doing the post first should be faster */
sem_post(&tid->sem_suspended);
do {
sem_wait(&tid->sem_selfsuspend);
} while (tid->selfsuspended); /* paranoid */
return 0;
}
int
np_suspend(sys_thread_t *tid)
{
int count, ret = 0;
int err = mutexLock(&sr_lock);
sysAssert(err == 0);
tid->selfsuspended = (tid == sysThreadSelf());
count = tid->suspend_count++;
#ifdef LOG_THREADS
dprintf(2, "[Suspending fromtid = %ld, tid = %ld, pid = %d, count = %d]\n",
pthread_self(), tid->sys_thread, tid->lwp_id, count);
#endif
if (count == 0) {
if (tid->selfsuspended) {
#ifdef LOG_THREADS
dprintf(2,
"[Self-suspending [tid = %ld, sys_thread = %ld]\n",
pthread_self(), tid->sys_thread);
#endif
mutexUnlock(&sr_lock);
do {
sem_wait(&tid->sem_selfsuspend);
} while (tid->selfsuspended);
/* [jk] What is the correct return value here?
There was no error, but when we return the thread
has already been resumed. */
return SYS_OK;
} else {
sr_tid = tid;
ret = pthread_kill(tid->sys_thread, sr_sigsusp);
if (ret == 0) {
sem_wait(&sr_sem);
}
#ifdef LOG_THREADS
dprintf(2,
"[Suspended fromtid = %ld, pthread_kill(%ld, %d) = %d]\n",
pthread_self(), tid->sys_thread, sr_sigsusp, ret);
#endif
}
}
err = mutexUnlock(&sr_lock);
sysAssert(err == 0);
return ret == 0 ? SYS_OK : SYS_ERR;
}
int
np_continue(sys_thread_t *tid)
{
int count, ret = 0;
int err = mutexLock(&sr_lock);
sysAssert(err == 0);
count = --tid->suspend_count;
#ifdef LOG_THREADS
dprintf(2, "[Resuming fromtid = %ld, tid = %ld, pid = %d, count = %d]\n",
pthread_self(), tid->sys_thread, tid->lwp_id, count);
#endif
if (count == 0) {
if (tid->selfsuspended) {
tid->selfsuspended = 0;
sem_post(&tid->sem_selfsuspend);
} else {
sr_tid = tid;
ret = pthread_kill(tid->sys_thread, sr_sigresu);
}
#ifdef LOG_THREADS
dprintf(2, "[Resumed fromtid = %ld, pthread_kill(%ld, %d) = %d]\n",
pthread_self(), tid->sys_thread, sr_sigresu, ret);
#endif
} else if (count < 0) {
/* Ignore attempts to resume a thread that has not been suspended */
tid->suspend_count = 0;
}
err = mutexUnlock(&sr_lock);
sysAssert(err == 0);
return ret == 0 ? SYS_OK : SYS_ERR;
}
/*
* Get the stack base and size.
*/
int
np_stackinfo(void **addr, long *size)
{
/* For now assume stack is 2 meg, from internals.h. */
#define STACK_SIZE (2 * 1024 * 1024)
void *p;
char *sp = (char *)&p; /* rougly %esp */
*addr = (void *)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
*size = STACK_SIZE;
return SYS_OK;
}
typedef unsigned long ulong_t;
#define VALID_SP(sp, bottom, top) \
(((ulong_t)(sp)) < ((ulong_t)(bottom)) && ((ulong_t)(sp)) > ((ulong_t)(top)))
/*
* Go into single threaded mode for GC.
*/
int
np_single()
{
sys_thread_t *tid;
pthread_t me = pthread_self();
int i;
#ifdef LOG_THREADS
dprintf(2, "[Entering np_single: thread count = %d]\n", ActiveThreadCount);
#endif
/* Stop all other threads. */
tid = ThreadQueue;
for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
if ((tid->sys_thread != me) && (tid->state != SUSPENDED)) {
np_suspend(tid);
sysAssert(VALID_SP(tid->sp, tid->stack_bottom, tid->stack_top));
tid->onproc = FALSE; /* REMIND: Might not need this */
}
tid = tid->next;
}
#ifdef LOG_THREADS
dprintf(2, "[Leaving np_single]\n");
#endif
return SYS_OK;
}
/*
* Per thread initialization.
*/
void
np_initialize_thread(sys_thread_t *tid)
{
sigset_t set;
/* Block SIGQUIT so that it can be handled by the SIGQUIT handler thread */
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
pthread_sigmask(SIG_BLOCK, &set, 0);
/* Set process id */
tid->lwp_id = getpid();
tid->suspend_count = 0;
/* Semaphore used for self-suspension */
sem_init(&tid->sem_selfsuspend, 0, 0);
tid->selfsuspended = 0;
#ifdef LOG_THREADS
dprintf(2, "[Init thread, tid = %ld, pid = %d, base = %p, size = %lu]\n",
pthread_self(), tid->lwp_id, tid->stack_bottom, tid->stack_size);
#endif
}
void
np_free_thread(sys_thread_t *tid)
{
sem_destroy(&tid->sem_selfsuspend);
}
/*
* Recover from single threaded mode after GC.
*/
void
np_multi()
{
int i;
sys_thread_t *tid;
pthread_t me = pthread_self();
tid = ThreadQueue;
for (i = 0; i < ActiveThreadCount && tid != 0; i++) {
if ((tid->sys_thread != me) && (tid->state != SUSPENDED)) {
np_continue(tid);
}
tid = tid->next;
}
}
void
np_profiler_init(sys_thread_t *tid)
{
}
int
np_profiler_suspend(sys_thread_t *tid)
{
return np_suspend(tid);
}
int
np_profiler_continue(sys_thread_t *tid)
{
return np_continue(tid);
}
bool_t
np_profiler_thread_is_running(sys_thread_t *tid)
{
return TRUE;
}
/*
* Copyright (c) 1994, 2000, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Threads interrupt dispatch
*/
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "hpi_impl.h"
#include "interrupt.h"
/* handler_entry_t is used to keep track of the registered handlers. */
typedef struct handler_entry {
intr_handler_t handler;
void *handlerArg;
} handler_entry_t;
static handler_entry_t handlerList[N_INTERRUPTS];
/* Initialize the interrupt system */
void
intrInit()
{
memset(handlerList, 0, sizeof(handlerList));
/*
* Target-dependent initialization.
*/
intrInitMD();
}
/* Add/Remove a handler for a particular interrupt */
signal_handler_t
intrRegister(int interrupt, intr_handler_t handler, void *handlerArg)
{
struct sigaction sigAct, sigActOld;
intrLock();
if (handler == (intr_handler_t)SYS_SIG_IGN ||
handler == (intr_handler_t)SYS_SIG_DFL) {
/* If we get IGN or DFL, register that as the process signal handler,
* and clear the handlerList entry.
*/
sigAct.sa_handler = (void (*)(int))handler;
sigAct.sa_flags = 0;
sigaction(interrupt, &sigAct, &sigActOld);
handlerList[interrupt].handler = NULL;
} else {
/* Otherwise, we register intrDispatchMD as the common signal handler,
* and set the real handler in handlerList[interrupt].handler.
*/
#ifdef SA_SIGINFO
sigAct.sa_handler = 0;
sigAct.sa_sigaction = intrDispatchMD;
sigAct.sa_flags = SA_SIGINFO | SA_RESTART;
#else
sigAct.sa_handler = intrDispatchMD;
sigAct.sa_flags = SA_RESTART;
#endif
sigfillset(&sigAct.sa_mask);
sigaction(interrupt, &sigAct, &sigActOld);
handlerList[interrupt].handler = handler;
handlerList[interrupt].handlerArg = handlerArg;
}
intrUnlock();
/* If SA_SIGINFO is set, sa_sigaction is valid, otherwise sa_handler is. */
#ifdef SA_SIGINFO
return (sigActOld.sa_flags & SA_SIGINFO) ?
(signal_handler_t)sigActOld.sa_sigaction :
(signal_handler_t)sigActOld.sa_handler;
#else
return (signal_handler_t)sigActOld.sa_handler;
#endif
}
/*
* intrDispatch -- Dispatch an interrupt.
*
* This routine is called from the low-level handlers
* at interrupt time.
*/
void
intrDispatch(int interrupt, void *siginfo, void *context)
{
/*
* Assumptions:
* - Each interrupt only has one priority level associated with
* it.
* - Each handler will do enough work so that when it returns
* the source of the interrupt is masked.
*/
handler_entry_t *entry = &handlerList[interrupt];
intr_handler_t handler = entry->handler;
if (handler) {
(*handler)(interrupt, siginfo, context, entry->handlerArg);
return;
}
/* No handler for this interrupt, log the error */
Log1(0, "spurious interrupt %d\n", interrupt);
return;
}
static void userSignalHandler(int sig, void *info, void *uc, void *arg)
{
signal_handler_t handler = (signal_handler_t)arg;
/* for now we don't change the disposition of the signal in this case */
/* sysSignal(sig, SYS_SIG_DFL); */
handler(sig, info, uc);
}
signal_handler_t sysSignal(int sig, signal_handler_t newHandler)
{
handler_entry_t *entry = &handlerList[sig];
void *oldHandlerArg = entry->handlerArg;
signal_handler_t oldHandler;
if (intrInUse(sig)) {
return SYS_SIG_ERR;
}
#ifdef __linux__
oldHandler = intrRegister(sig, (intr_handler_t)userSignalHandler, (void *)newHandler);
#else
oldHandler = intrRegister(sig, userSignalHandler, (void *)newHandler);
#endif
/* If the old handler is intrDispatchMD, we get the real handler from
* entry->handlerArg.
*/
if (oldHandler == (signal_handler_t)intrDispatchMD) {
oldHandler = (signal_handler_t)oldHandlerArg;
}
return oldHandler;
}
void sysRaise(int sig)
{
raise(sig);
}
/*
* Copyright (c) 1994, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Machine Dependent implementation of the dynamic linking support
* for java. This routine is Solaris specific.
*/
#include "hpi_impl.h"
#include <stdio.h>
#include <dlfcn.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "path_md.h"
#include "monitor_md.h"
#ifndef NATIVE
#include "iomgr.h"
#include "threads_md.h"
#endif
/*
* This lock protects the dl wrappers, assuring that two threads aren't
* in libdl at the same time.
*/
sys_mon_t _dl_lock;
/*
* Solaris green threads needs to lock around libdl.so.
*/
#if defined(__solaris__) && !defined(NATIVE)
#define NEED_DL_LOCK
#endif
/*
* create a string for the JNI native function name by adding the
* appropriate decorations.
*/
int
sysBuildFunName(char *name, int nameLen, int args_size, int encodingIndex)
{
/* On Solaris, there is only one encoding method. */
if (encodingIndex == 0)
return 1;
return 0;
}
/*
* create a string for the dynamic lib open call by adding the
* appropriate pre and extensions to a filename and the path
*/
void
sysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
{
const size_t pnamelen = pname ? strlen(pname) : 0;
/* Quietly truncate on buffer overflow. Should be an error. */
if (pnamelen + strlen(fname) + 10 > (size_t) holderlen) {
*holder = '\0';
return;
}
if (pnamelen == 0) {
sprintf(holder, "lib%s.so", fname);
} else {
sprintf(holder, "%s/lib%s.so", pname, fname);
}
}
#ifdef __linux__
static int thr_main(void)
{
return -1;
}
#else
#ifndef NATIVE
extern int thr_main(void);
#endif
#endif
void *
sysLoadLibrary(const char *name, char *err_buf, int err_buflen)
{
void * result;
#ifdef NEED_DL_LOCK
sysMonitorEnter(sysThreadSelf(), &_dl_lock);
result = dlopen(name, RTLD_NOW);
sysMonitorExit(sysThreadSelf(), &_dl_lock);
#else
result = dlopen(name, RTLD_LAZY);
#endif
/*
* This is a bit of bulletproofing to catch the commonly occurring
* problem of people loading a library which depends on libthread into
* the VM. thr_main() should always return -1 which means that libthread
* isn't loaded.
*/
#ifndef NATIVE
if (thr_main() != -1) {
VM_CALL(panic)("libthread loaded into green threads");
}
#endif
if (result == NULL) {
strncpy(err_buf, dlerror(), err_buflen-2);
err_buf[err_buflen-1] = '\0';
}
return result;
}
void
sysUnloadLibrary(void *handle)
{
#ifdef NEED_DL_LOCK
sysMonitorEnter(sysThreadSelf(), &_dl_lock);
dlclose(handle);
sysMonitorExit(sysThreadSelf(), &_dl_lock);
#else
dlclose(handle);
#endif
}
void *
sysFindLibraryEntry(void *handle, const char *name)
{
void *sym;
#ifdef NEED_DL_LOCK
sysMonitorEnter(sysThreadSelf(), &_dl_lock);
sym = dlsym(handle, name);
sysMonitorExit(sysThreadSelf(), &_dl_lock);
#else
sym = dlsym(handle, name);
#endif
return sym;
}
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*-
* Win32 dependent machine byte ordering (actually intel ordering)
*/
#ifndef _JAVASOFT_WIN32_BYTEORDER_MD_H_
#define _JAVASOFT_WIN32_BYTEORDER_MD_H_
#ifdef x86
#define ntohl(x) ((x << 24) | \
((x & 0x0000ff00) << 8) | \
((x & 0x00ff0000) >> 8) | \
(((unsigned long)(x & 0xff000000)) >> 24))
#define ntohs(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
#define htonl(x) ntohl(x)
#define htons(x) ntohs(x)
#else /* x86 */
#define ntohl(x) (x)
#define ntohs(x) (x)
#define htonl(x) (x)
#define htons(x) (x)
#endif /* x86 */
#endif /* !_JAVASOFT_WIN32_BYTEORDER_MD_H_ */
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef _JAVASOFT_HPI_MD_H_
#define _JAVASOFT_HPI_MD_H_
#include "timeval_md.h"
#include "io_md.h"
#include "path_md.h"
#include "byteorder_md.h"
#define HPI_TIMEOUT_INFINITY ((jlong)(-1))
#endif /* !_JAVASOFT_HPI_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* Win32 system dependent low level io definitions
*/
#ifndef _JAVASOFT_WIN32_IO_MD_H_
#define _JAVASOFT_WIN32_IO_MD_H_
#include <stdio.h>
#include <io.h> /* For read(), lseek() etc. */
#include <direct.h> /* For mkdir() */
#include <windows.h>
#include <winsock.h>
#include <sys/types.h>
#include <ctype.h>
#include <stdlib.h>
#include "jvm_md.h"
#define R_OK 4
#define W_OK 2
#define X_OK 1
#define F_OK 0
#define MAXPATHLEN _MAX_PATH
#define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO)
#define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR)
#define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR)
#define S_ISREG(mode) (((mode) & _S_IFREG) == _S_IFREG)
#define LINE_SEPARATOR "\r\n"
#endif /* !_JAVASOFT_WIN32_IO_MD_H_ */
/*
* Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*-
* Win32 dependent search path definitions and API
*/
#ifndef _JAVASOFT_WIN32_PATH_MD_H_
#define _JAVASOFT_WIN32_PATH_MD_H_
#define PATH_SEPARATOR ";"
#define PATH_CURDIR "."
#define DIR_SEPARATOR '/'
#define LOCAL_DIR_SEPARATOR '\\'
#endif /* !_JAVASOFT_WIN32_PATH_MD_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册