Break Unsafe apart into Unsafe and UnsafeGC, the latter having only the

things to play with garbage collection. The gc stuff required JVMPI which the
"server" jvm doesn't have, so poor saps like me with two processors and gobs
of ram needed to hack things  to run yohoho & force java to run with the 
"client" vm since it used stuff out of unsafe (but not the gc stuff)

Still need to hit up people to build me the shared objects on other platforms,
but the linux ones are there & working.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@398 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Dave Hoover
2008-01-17 23:10:46 +00:00
parent f91b7714a5
commit 406b2a4662
15 changed files with 260 additions and 119 deletions
@@ -22,24 +22,32 @@ INSTALL_PATH=${ROOT}/dist/lib/i386-FreeBSD
INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/${OSINCDIR}
LIBRARIES=
TARGET=libunsafe.so
TARGETS=libunsafe.so libunsafegc.so
#
# Target definitions
all: ${TARGET}
all: ${TARGETS}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
cp ${TARGETS} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling Unsafe.c"
libunsafe.so: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo "Creating libunsafe.so"
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
@echo "Creating $@"
@${CC} -o libunsafe.so com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
libunsafegc.so: com_threerings_util_unsafe_UnsafeGC.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_UnsafeGC.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo "Creating $@"
@${CC} -o libunsafegc.so com_threerings_util_unsafe_Unsafegc.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
clean:
-${RM} -f *.o ${TARGET}
-${RM} -f *.o ${TARGETS}
@@ -4,7 +4,6 @@
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include <errno.h>
#include <sys/types.h>
@@ -13,9 +12,6 @@
#include "com_threerings_util_unsafe_Unsafe.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
/** A sleep method that uses select(). This seems to have about 10ms
* granularity where nanosleep() has about 20ms. Sigh. */
static int select_sleep (int millisecs)
@@ -28,18 +24,6 @@ static int select_sleep (int millisecs)
return select(0, &dummy, NULL, NULL, &toWait);
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz)
{
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz)
{
jvmpi->DisableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSleep (
JNIEnv* env, jclass clazz, jint millis)
@@ -100,18 +84,5 @@ JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetegid
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -0,0 +1,49 @@
/*
* $Id$
*/
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include <errno.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "com_threerings_util_unsafe_UnsafeGC.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_UnsafeGC_enableGC (JNIEnv* env, jclass clazz)
{
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_UnsafeGC_disableGC (JNIEnv* env, jclass clazz)
{
jvmpi->DisableGC();
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_UnsafeGC_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -21,24 +21,32 @@ INSTALL_PATH=${ROOT}/dist/lib/i686-Linux
INCLUDES=-I.. -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux
LIBRARIES=-lX11
TARGET=libunsafe.so
TARGETS=libunsafe.so libunsafegc.so
#
# Target definitions
all: ${TARGET}
all: ${TARGETS}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
cp ${TARGETS} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
@echo Compiling Unsafe.c
libunsafe.so: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo Creating ${TARGET}
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
@echo "Creating $@"
@${CC} -o libunsafe.so com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
libunsafegc.so: com_threerings_util_unsafe_UnsafeGC.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_UnsafeGC.c \
-o com_threerings_util_unsafe_UnsafeGC.o
@echo "Creating $@"
@${CC} -o libunsafegc.so com_threerings_util_unsafe_UnsafeGC.o \
${LIBRARIES} ${LIBRARIES_PATH} -shared
clean:
-${RM} -f *.o ${TARGET}
-${RM} -f *.o ${TARGETS}
@@ -0,0 +1 @@
../FreeBSD/com_threerings_util_unsafe_UnsafeGC.c
Binary file not shown.
@@ -22,24 +22,32 @@ INSTALL_PATH=${ROOT}/dist/lib/`uname -m`-Darwin
INCLUDES=-I.. -I/System/Library/Frameworks/JavaVM.framework/Headers
LIBRARIES=
TARGET=libunsafe.jnilib
TARGETS=libunsafe.jnilib libunsafegc.jnilib
#
# Target definitions
all: ${TARGET}
all: ${TARGETS}
install:
@${MKDIR} -p ${INSTALL_PATH}
cp ${TARGET} ${INSTALL_PATH}
cp ${TARGETS} ${INSTALL_PATH}
${TARGET}: com_threerings_util_unsafe_Unsafe.c
libunsafe.jnilib: com_threerings_util_unsafe_Unsafe.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_Unsafe.c \
-o com_threerings_util_unsafe_Unsafe.o
@echo "Creating $@"
@${CC} -o ${TARGET} com_threerings_util_unsafe_Unsafe.o \
@${CC} -o libunsafe.jnilib com_threerings_util_unsafe_Unsafe.o \
${LIBRARIES} ${LIBRARIES_PATH} -dynamiclib
libunsafegc.jnilib: com_threerings_util_unsafe_UnsafeGC.c
@echo "Compiling $<"
@${CC} ${INCLUDES} -c com_threerings_util_unsafe_UnsafeGC.c \
-o com_threerings_util_unsafe_UnsafeGC.o
@echo "Creating $@"
@${CC} -o libunsafegc.jnilib com_threerings_util_unsafe_UnsafeGC.o \
${LIBRARIES} ${LIBRARIES_PATH} -dynamiclib
clean:
-${RM} -f *.o ${TARGET}
-${RM} -f *.o ${TARGETS}
@@ -0,0 +1 @@
../FreeBSD/com_threerings_util_unsafe_UnsafeGC.c
@@ -32,27 +32,6 @@ import static com.threerings.NenyaLog.log;
*/
public class Unsafe
{
/**
* Enables or disables garbage collection. <em>Warning:</em> you will
* be fucked if you leave it disabled for too long. Do not do this
* unless you are dang sure about what you're doing and are prepared
* to test your code on every platform this side of Nantucket.
*
* <p> Calls to this method do not nest. Regardless of how many times
* you disable GC, only one call is required to reenable it.
*/
public static void setGCEnabled (boolean enabled)
{
// we don't support nesting, NOOP if the state doesn't change
if (_loaded && enabled != _gcEnabled) {
if (_gcEnabled = enabled) {
enableGC();
} else {
disableGC();
}
}
}
/**
* Causes the current thread to block for the specified number of
* milliseconds. This exists primarily to work around the fact that on
@@ -172,6 +151,7 @@ public class Unsafe
static {
try {
System.out.println("Tring to load unsafe");
System.loadLibrary("unsafe");
_loaded = init();
} catch (SecurityException se) {
@@ -0,0 +1,88 @@
//
// $Id$
//
// Nenya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/nenya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.util.unsafe;
import com.samskivert.util.RunAnywhere;
import static com.threerings.NenyaLog.log;
/**
* A native library for doing unsafe things involving garbage collection.
* Don't use this library. If you must ignore that warning, then be sure you use it
* sparingly and only in very well considered cases.
*/
public class UnsafeGC
{
/**
* Enables or disables garbage collection. <em>Warning:</em> you will
* be fucked if you leave it disabled for too long. Do not do this
* unless you are dang sure about what you're doing and are prepared
* to test your code on every platform this side of Nantucket.
*
* <p> Calls to this method do not nest. Regardless of how many times
* you disable GC, only one call is required to reenable it.
*/
public static void setGCEnabled (boolean enabled)
{
// we don't support nesting, NOOP if the state doesn't change
if (_loaded && enabled != _gcEnabled) {
if (_gcEnabled = enabled) {
enableGC();
} else {
disableGC();
}
}
}
/**
* Reenable garbage collection after a call to {@link #disableGC}.
*/
protected static native void enableGC ();
/**
* Disables garbage collection.
*/
protected static native void disableGC ();
/**
* Called to initialize our library.
*/
protected static native boolean init ();
/** The current state of GC enablement. */
protected static boolean _gcEnabled = true;
/** Whether or not we were able to load and initialize our library. */
protected static boolean _loaded;
static {
try {
System.loadLibrary("unsafegc");
_loaded = init();
} catch (SecurityException se) {
log.warning("Failed to load 'unsafegc' library: " + se + ".");
} catch (UnsatisfiedLinkError e) {
log.warning("Failed to load 'unsafegc' library: " + e + ".");
}
}
}
@@ -4,27 +4,9 @@
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include "com_threerings_util_unsafe_Unsafe.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Reenabling GC.\n");
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Disabling GC.\n");
jvmpi->DisableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_nativeSleep (
JNIEnv* env, jclass clazz, jint millis)
@@ -63,18 +45,5 @@ JNIEXPORT jboolean JNICALL Java_com_threerings_util_unsafe_Unsafe_nativeSetegid
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -0,0 +1,45 @@
/*
* $Id: com_threerings_util_unsafe_Unsafe.c 3331 2005-02-03 01:25:21Z mdb $
*/
#include <stdio.h>
#include <jni.h>
#include <jvmpi.h>
#include "com_threerings_util_unsafe_UnsafeGC.h"
/* global jvmpi interface pointer */
static JVMPI_Interface* jvmpi;
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_enableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Reenabling GC.\n");
jvmpi->EnableGC();
}
JNIEXPORT void JNICALL
Java_com_threerings_util_unsafe_Unsafe_disableGC (JNIEnv* env, jclass clazz)
{
fprintf(stderr, "Disabling GC.\n");
jvmpi->DisableGC();
}
JNIEXPORT jboolean JNICALL
Java_com_threerings_util_unsafe_Unsafe_init (JNIEnv* env, jclass clazz)
{
JavaVM* jvm;
if ((*env)->GetJavaVM(env, &jvm) > 0) {
fprintf(stderr, "Failed to get JavaVM from env.\n");
return JNI_FALSE;
}
/* get jvmpi interface pointer */
if (((*jvm)->GetEnv(jvm, (void**)&jvmpi, JVMPI_VERSION_1)) < 0) {
fprintf(stderr, "Failed to get JVMPI from JavaVM.\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
@@ -7,22 +7,6 @@
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: enableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_enableGC
(JNIEnv *, jclass);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: disableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_disableGC
(JNIEnv *, jclass);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: nativeSleep
@@ -0,0 +1,29 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_threerings_util_unsafe_Unsafe */
#ifndef _Included_com_threerings_util_unsafe_Unsafe
#define _Included_com_threerings_util_unsafe_Unsafe
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: enableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_enableGC
(JNIEnv *, jclass);
/*
* Class: com_threerings_util_unsafe_Unsafe
* Method: disableGC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_threerings_util_unsafe_Unsafe_disableGC
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif