This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: finalizer thread - please comment
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Subject: Patch: finalizer thread - please comment
- From: Tom Tromey <tromey at redhat dot com>
- Date: 04 Oct 2001 09:03:54 -0600
- Reply-To: tromey at redhat dot com
Java requires that finalizers be run in their own thread. Actually I
think it requires that a finalizer be run when no user-visible locks
are held; this amounts to the same thing.
The appended patch implements this. It builds and checks fine on x86
RH Linux 6.2.
If I check this in it will break the no-thread build. What should we
do about this? I can think of a few things.
One idea would be to lazily create the new thread insie
FinalizerThread itself. Then we could catch an exception when the
thread is made (and change no-threads.cc to throw an exception) and
just run finalizers in the main thread (or not run them at all, which
might be more correct).
There are other choices too. For instance we could simply deprecate
the no-thread build.
Other ideas?
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Added
FinalizerThread.java.
* include/jvm.h (_Jv_GCInitializeFinalizers): Declare.
* boehm.cc (_Jv_GCInitializeFinalizers): New function.
* posix-threads.cc (_Jv_InitThreads): Call
_Jv_GCInitializeFinalizers.
Include FinalizerThread.h.
* gnu/gcj/runtime/FirstThread.java (run): Start finalizer thread.
* gnu/gcj/runtime/FinalizerThread.java: New file.
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libjava/Makefile.am,v
retrieving revision 1.174
diff -u -r1.174 Makefile.am
--- Makefile.am 2001/10/02 22:49:53 1.174
+++ Makefile.am 2001/10/04 14:40:45
@@ -1137,6 +1137,7 @@
gnu/gcj/protocol/jar/Connection.java \
gnu/gcj/protocol/jar/Handler.java \
gnu/gcj/runtime/FileDeleter.java \
+gnu/gcj/runtime/FinalizerThread.java \
gnu/gcj/runtime/FirstThread.java \
gnu/gcj/runtime/SharedLibLoader.java \
gnu/gcj/runtime/VMClassLoader.java \
Index: boehm.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/boehm.cc,v
retrieving revision 1.28
diff -u -r1.28 boehm.cc
--- boehm.cc 2001/10/02 14:31:42 1.28
+++ boehm.cc 2001/10/04 14:40:48
@@ -544,6 +544,13 @@
#endif /* JV_HASH_SYNCHRONIZATION */
void
+_Jv_GCInitializeFinalizers (void (*notifier) (void))
+{
+ GC_finalize_on_demand = 1;
+ GC_finalizer_notifier = notifier;
+}
+
+void
_Jv_GCRegisterDisappearingLink (jobject *objp)
{
GC_general_register_disappearing_link ((GC_PTR *) objp, (GC_PTR) *objp);
Index: posix-threads.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/posix-threads.cc,v
retrieving revision 1.28
diff -u -r1.28 posix-threads.cc
--- posix-threads.cc 2001/09/21 04:23:31 1.28
+++ posix-threads.cc 2001/10/04 14:40:48
@@ -31,6 +31,7 @@
#include <java/lang/System.h>
#include <java/lang/Long.h>
#include <java/lang/OutOfMemoryError.h>
+#include <gnu/gcj/runtime/FinalizerThread.h>
// This is used to implement thread startup.
struct starter
@@ -291,6 +292,8 @@
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (INTR, &act, NULL);
+
+ _Jv_GCInitializeFinalizers (&::gnu::gcj::runtime::FinalizerThread::finalizerReady);
}
_Jv_Thread_t *
Index: gnu/gcj/runtime/FinalizerThread.java
===================================================================
RCS file: FinalizerThread.java
diff -N FinalizerThread.java
--- /dev/null Tue May 5 13:32:27 1998
+++ gnu/gcj/runtime/FinalizerThread.java Thu Oct 4 07:40:49 2001
@@ -0,0 +1,60 @@
+// FinalizerThread.java -- Thread in which finalizers are run.
+
+/* Copyright (C) 2001 Free Software Foundation
+
+ This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
+details. */
+
+package gnu.gcj.runtime;
+
+/**
+ * @author Tom Tromey <tromey@redhat.com>
+ * @date October 3, 2001
+ */
+public final class FinalizerThread extends Thread
+{
+ // Finalizers must be run in a thread with no Java-visible locks
+ // held. This qualifies because we don't make the lock visible.
+ private static final Object lock = new Object ();
+
+ public FinalizerThread ()
+ {
+ super ();
+ setDaemon (true);
+ }
+
+ // This is called by the runtime when a finalizer is ready to be
+ // run. It simply wakes up the finalizer thread.
+ public static void finalizerReady ()
+ {
+ synchronized (lock)
+ {
+ lock.notify ();
+ }
+ }
+
+ public void run ()
+ {
+ // Wait on a lock. Whenever we wake up, try to invoke the
+ // finalizers.
+ synchronized (lock)
+ {
+ while (true)
+ {
+ try
+ {
+ lock.wait ();
+ }
+ catch (InterruptedException _)
+ {
+ // Just ignore it. It doesn't hurt to run finalizers
+ // when none are pending.
+ }
+ Runtime.getRuntime ().runFinalization ();
+ }
+ }
+ }
+}
Index: gnu/gcj/runtime/FirstThread.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/runtime/FirstThread.java,v
retrieving revision 1.9
diff -u -r1.9 FirstThread.java
--- gnu/gcj/runtime/FirstThread.java 2001/08/26 11:30:08 1.9
+++ gnu/gcj/runtime/FirstThread.java 2001/10/04 14:40:49
@@ -1,6 +1,6 @@
// FirstThread.java - Implementation of very first thread.
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
+/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
This file is part of libgcj.
@@ -33,12 +33,15 @@
this.args = args;
this.is_jar = is_jar;
}
-
+
public void run()
{
+ // Start the GC finalizer thread.
+ new FinalizerThread ().start ();
+
if (is_jar)
klass_name = getMain(klass_name);
-
+
if (klass == null)
{
try
@@ -50,7 +53,7 @@
throw new NoClassDefFoundError(klass_name);
}
}
-
+
call_main();
}
Index: include/jvm.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/jvm.h,v
retrieving revision 1.41
diff -u -r1.41 jvm.h
--- include/jvm.h 2001/10/02 14:31:45 1.41
+++ include/jvm.h 2001/10/04 14:40:50
@@ -157,6 +157,9 @@
memory. */
void *_Jv_MallocUnchecked (jsize size) __attribute__((__malloc__));
+/* Initialize finalizers. The argument is a function to be called
+ when a finalizer is ready to be run. */
+void _Jv_GCInitializeFinalizers (void (*notifier) (void));
/* Run finalizers for objects ready to be finalized.. */
void _Jv_RunFinalizers (void);
/* Run all finalizers. Should be called only before exit. */