[java] The thread pool now works when Mercury is used as a library

The thread pool code used in the Java backend was tied the execution of
main/2.  However if Mercury is used as a library the thread pool won't have
been started and threads created with thread.spawn would not be executed.

This patch makes it possible to start and stop the thread pool independently of
main/2 by calling startup() and shutdown().  These calls are called
implicitly by calling runMain().  The thread pool can also be started on
demand.

This patch also adds the MercuryRuntime class, which now contains methods
that may be called by users' Java code to interact with the Mercury runtime
system, including a new finalise() method.

java/runtime/MercuryThreadPool.java:
    Add startup() method.

    shutdown() method is now public and it's meaning has changed, it now
    requests the shutdown rather than performing it.

    Renamed some variables to make their meanings clearer.

java/runtime/JavaInternal.java:
    Initialise the ThreadPool and MercuryOptions objects on demand.

    Make all members of this class static to avoid confusion.

    Add a private constructor.

java/runtime/MercuryRuntime.java:
    Add methods that can be called by Mercury users to interact with the
    runtime system.  Including a convenient finalise() method that does all
    the finalisation.

samples/java_interface/standalone_java/mercury_lib.m:
samples/java_interface/standalone_java/JavaMain.java:
    Extend the standalone Java example so that it makes use of threads: Add
    a fibs function in Mercury that uses concurrency and therefore starts
    the thread pool; call it from the Java code.

    Use the new finalise() method from the MercuryRuntime class inside of a
    finally block.

samples/java_interface/standalone_java/Makefile:
    Fix a minor error.
This commit is contained in:
Paul Bone
2014-12-15 11:04:28 +11:00
parent 0b5e06e4ac
commit e4a0adf424
6 changed files with 296 additions and 58 deletions

View File

@@ -1,10 +1,10 @@
// vim: ts=4 sw=4 et
// The JavaInternal class in the jmercury.runtime package provides various
// The MercuryRuntime class in the jmercury.runtime package provides various
// Mercury runtime services that we may require.
// All Mercury runtime and generated Java code lives in the jmercury package.
//
import jmercury.runtime.JavaInternal;
import jmercury.runtime.MercuryRuntime;
// The mercury_lib class is generated by the compiler when we build
// mercury_lib library.
@@ -20,9 +20,36 @@ public class JavaMain {
// We do not need to do anything to initialise the Java version of the
// Mercury runtime. It will be automatically initialised as the
// relevant classes are loaded by the JVM.
out.println("JavaMain: start main");
try {
runProgram(args);
} finally {
// When we have finished calling Mercury procedures then we need to
// tell the Mercury Runtime that we've finished using it.
// This invokes any finalisers specified using ':- finalise'
// declarations in the set of Mercury libraries we are using. It
// also tells the thread pool to shutdown, if the thread pool is not
// runnuing then this does nothing.
// The static method finalise() in the MercuryRuntime class does
// this.
//
MercuryRuntime.finalise();
// The Mercury exit status (as set by io.set_exit_status/1) may
// be read from the MercuryRuntime class.
//
out.println("JavaMain: Mercury exit status = "
+ MercuryRuntime.getExitStatus());
out.println("JavaMain: end main");
}
System.exit(MercuryRuntime.getExitStatus());
}
public static void runProgram(String[] args) {
// This is a call to an exported Mercury procedure that does some I/O.
// The mercury_lib class contains a static method for each procedure
// that is foreign exported to Java.
@@ -33,21 +60,7 @@ public class JavaMain {
//
out.println("3^3 = " + mercury_lib.cube(3));
// When we have finished calling Mercury procedures then we need to
// invoke any finalisers specified using ':- finalise' declarations in
// the set of Mercury libraries we are using.
// The static method run_finalisers() in the JavaInternal class does
// this. It will also perform any Mercury runtime finalisation that
// may be needed.
//
JavaInternal.run_finalisers();
// The Mercury exit status (as set by io.set_exit_status/1) may be read
// from the static field 'exit_status' in the JavaInternal class.
//
out.println("JavaMain: Mercury exit status = "
+ JavaInternal.exit_status);
out.println("JavaMain: end main");
// Try a parallelised Mercury function.
out.println("fibs(40) = " + mercury_lib.fibs(40));
}
}

View File

@@ -14,7 +14,7 @@ MER_JARS = $(MER_LIB_DIR)/mer_std.jar:$(MER_LIB_DIR)/mer_rt.jar
.PHONY: all
all: run
JavaMain.class: JavaMain.java mercury_lib.jar
JavaMain.class: JavaMain.java libmercury_lib.jar
$(JAVAC) JavaMain.java -cp $(MER_JARS):Mercury/classs -d .
libmercury_lib.jar: mercury_lib.m

View File

@@ -17,6 +17,11 @@
%
:- func cube(int) = int.
% fibs(N) returns the Nth fibbonanci number using a parallelised naive
% algorithm.
%
:- func fibs(int) = int.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -25,6 +30,8 @@
:- import_module int.
:- import_module list.
:- import_module string.
:- import_module thread.
:- import_module thread.future.
%-----------------------------------------------------------------------------%
@@ -41,6 +48,41 @@ write_hello(!IO) :-
cube(X) = X * X * X.
%-----------------------------------------------------------------------------%
%
% Trivial concurrency test. No one would normally write fibs this way.
%
:- pragma foreign_export("Java", fibs(in) = out,
"fibs").
fibs(N) = fibs_par(N).
:- func fibs_par(int) = int.
fibs_par(N) = F :-
( N < 2 ->
F = 1
; N > fibs_thresh ->
F2 = future((func) = fibs_par(N-2)),
F1 = fibs_par(N-1),
F = F1 + wait(F2)
;
F = fibs_seq(N-1) + fibs_seq(N-2)
).
:- func fibs_seq(int) = int.
fibs_seq(N) =
( N < 2 ->
1
;
fibs_seq(N-2) + fibs_seq(N-1)
).
:- func fibs_thresh = int.
fibs_thresh = 20.
%-----------------------------------------------------------------------------%
%
% Initialiser for this library