// java/runtime/Native.java.  Generated from Native.java.in by configure.
//
// Copyright (C) 2004, 2006 The University of Melbourne.
// This file may only be copied under the terms of the GNU Library General
// Public License - see the file COPYING.LIB in the Mercury distribution.
//
//
// This class exists to provide any native functionality required by the Java
// implementation.  It uses JNI to access a shared object which it searches
// for in all the directories listed in the current CLASSPATH.
// 
// At the moment the only services provided are those relating to timing.
//

package jmercury.runtime;

public class Native {
	/*
	** SHARED_OBJ is the name of the shared object which contains all the
	** compiled native code.
	*/
	private	static final java.lang.String	SHARED_OBJ =
			"Native.so";

	/*
	** 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 {
		load_library();
	}

	/*
	** load_library():
	** 	Searches all the directories listed in the classpath,
	** 	(including the directories containing each jar file) for
	** 	the shared object SHARED_OBJ and attempts to load this file
	** 	if found.
	**	Also searches in the subdirectory Constants.MR_FULLARCH.
	** 	Sets available to true if successful, false otherwise.
	*/
	private static void load_library() {
		attemptedLoad = true;

		java.util.StringTokenizer classpath =
				new java.util.StringTokenizer(
				java.lang.System.getProperty("java.class.path")
				,java.lang.System.getProperty("path.separator")
				);

		while (classpath.hasMoreTokens()) {
			java.io.File dir;
			java.io.File entry = new java.io.File(
					classpath.nextToken());

			try {
				if (entry.isDirectory()) {
					dir = entry;
				} else {
					dir = entry.getParentFile();
				}
				if (dir == null) {
					dir = new java.io.File("");
				}

				java.io.File match = new java.io.File(dir,
						SHARED_OBJ);
				if (match.exists() == false) {
					dir = new java.io.File(dir,
						Constants.MR_FULLARCH);
					match = new java.io.File(dir,
						SHARED_OBJ);
				}

				java.lang.System.load(match.getAbsolutePath());
				available = true;
				return;
			}
			catch (java.lang.Exception e) {
				continue;
			}
		} // while classpath.hasMoreTokens()

		return;
	} // load_library()

	/*
	** clock():
	** 	Calls clock() from the <time.h> library.
	*/
	public static native int clock();

	/*
	** clocks_per_sec():
	**	Returns the number of "clocks" per sec as defined by
	**	CLOCKS_PER_SEC.
	*/
	public static native int clocks_per_sec();

	/*
	** times():
	** 	Calls times() from the <time.h> library.  Results are returned
	** 	in an int array of the form:
	**	{ <return value>, utime, stime, cutime, cstime }
	**	If POSIX times are not available, <return value> will be set
	**	to -1, and the other values are undefined.
	**	Returns null if the array cannot be constructed.
	*/
	public static native int[] times();

	/*
	** clk_tck():
	**	Returns the number of "clock ticks" per second as defined by
	**	sysconf(_SC_CLK_TCK).  A `clock_t' value returned by
	**	'times()' can be divided by this value to obtain a time in
	**	seconds.
	*/
	public static native int clk_tck();

	/*
	** get_user_cpu_milliseconds():
	**	Native method to return the CPU time consumed by the process,
	**	in milliseconds, from an arbitrary initial time.
	*/
	public static native int get_user_cpu_milliseconds();
}

