diff --git a/java/runtime/Native.java.in b/java/runtime/Native.java.in index 4c6d1bc25..2ecd33a13 100644 --- a/java/runtime/Native.java.in +++ b/java/runtime/Native.java.in @@ -21,18 +21,31 @@ public class Native { private static final java.lang.String SHARED_OBJ = "Native.@EXT_FOR_SHARED_LIB@"; + /* + ** attemptedLoad records whether or not the user has yet attempted to + ** load the shared library. + */ + private static boolean attemptedLoad = false; + /* ** available and isAvailable() are true when native functionality ** is available. (ie SHARED_OBJ was loaded successfully) */ private static boolean available = false; + /* + ** isAvailable() as the side effect of attempting to load the library + ** if this has not already been done. + */ public static boolean isAvailable() { + if (!attemptedLoad) { + load_library(); + } return available; } static { - available = load_library(); + load_library(); } /* @@ -42,9 +55,11 @@ public class Native { ** the shared object SHARED_OBJ and attempts to load this file ** if found. ** Also searches in the subdirectory Constants.MR_FULLARCH. - ** Returns true if successful, false otherwise. + ** Sets available to true if successful, false otherwise. */ - private static boolean load_library() { + private static void load_library() { + attemptedLoad = true; + java.util.StringTokenizer classpath = new java.util.StringTokenizer( java.lang.System.getProperty("java.class.path") @@ -77,14 +92,15 @@ public class Native { } java.lang.System.load(match.getAbsolutePath()); - return true; + available = true; + return; } catch (java.lang.Exception e) { continue; } } // while classpath.hasMoreTokens() - return false; + return; } // load_library() /* diff --git a/library/benchmarking.m b/library/benchmarking.m index 7f9949338..f136ef4ae 100644 --- a/library/benchmarking.m +++ b/library/benchmarking.m @@ -93,6 +93,18 @@ extern void ML_report_full_memory_stats(void); #endif "). +:- pragma foreign_proc("Java", report_stats, + [may_call_mercury], +" + ML_report_stats(); +"). + +:- pragma foreign_proc("Java", report_full_memory_stats, + [will_not_call_mercury], +" + ML_report_full_memory_stats(); +"). + %-----------------------------------------------------------------------------% :- pragma foreign_code("C", " @@ -581,6 +593,52 @@ ML_memory_profile_compare_final(const void *i1, const void *i2) #endif /* MR_MPROF_PROFILE_MEMORY */ "). +:- pragma foreign_code("Java", +" +private static int time_at_start = 0; +private static int time_at_last_stat = 0; + +static { + if (mercury.runtime.Native.isAvailable()) { + time_at_start = mercury.runtime.Native. + get_user_cpu_miliseconds(); + time_at_last_stat = time_at_start; + } +} + +private static void +ML_report_stats() { + int time_at_prev_stat = time_at_last_stat; + time_at_last_stat = get_user_cpu_miliseconds_1_p_0(); + + System.err.print(""[Time: "" + + ((time_at_last_stat - time_at_prev_stat) / 1000.0) + + "", "" + + ((time_at_last_stat - time_at_start) / 1000.0) + ); + + /* + ** XXX At this point there should be a whole bunch of memory usage + ** statistics. Unfortunately the Java back-end does not yet + ** support this amount of profiling, so cpu time is all you get. + */ + + System.err.println(""]""); +} + +private static void +ML_report_full_memory_stats() { + /* + ** XXX The support for this predicate is even worse. Since we don't + ** have access to memory usage statistics, all you get here is an + ** apology. But at least it doesn't just crash with an error. + */ + + System.err.println(""Sorry, report_full_memory_stats is not yet "" + + ""implemented for the Java back-end.""); +} +"). + %-----------------------------------------------------------------------------% :- pragma promise_pure(benchmark_det/5).