#include "toba.h"
#include "java_lang_Runtime.h"

#ifndef SCOUT
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#endif /* ! SCOUT */

#include "runtime.h"
#include "../gc/gc.h"

#ifdef linux
#include <stdio.h>
#endif

/* java/lang/Runtime exitInternal (I)V */
Void exitInternal_i_zIKEN(Object Harg1, Int arg2)
/*ARGSUSED*/
{
    terminate(arg2);
}

/* java/lang/Runtime execInternal ([Ljava/lang/String;[Ljava/lang/String;)Ljava/lang/Process; */
Object execInternal_aSaS_pYOyC(Object Harg1, Object Harg2, Object Harg3)
/*ARGSUSED*/
{
    /* Harg3 can be null but Harg2 cannot */
    if(! Harg2)
        throwNullPointerException(0);

    /* return the appropriate subclass of java.lang.Process */
    return create_process(Harg2, Harg3);
}

#if defined(linux) && ! defined(SCOUT)
Long getFreeMemory() {
    long freeMem, freeSwap;
    FILE *memfile = fopen("/proc/meminfo", "r");
    fscanf(memfile, "%*[^\n]\n");
    fscanf(memfile, "%*s %*d %*d %ld %*[^\n]\n", &freeMem);
    fscanf(memfile, "%*s %*d %*d %ld %*[^\n]\n", &freeSwap);
    fclose(memfile);
    return (Long)freeMem + (Long)freeSwap;
}
#endif /* linux && ! SCOUT */

/* java/lang/Runtime freeMemory ()J */
Long freeMemory__Ivacq(Object Harg1)
/*ARGSUSED*/
{
#undef HAVE_freeMemory
#if defined(__CYGWIN32__)
#define HAVE_freeMemory (1)
    return 10 * 1024 * 1024; /* XXX */
#endif /* __CYGWIN32__ */
#if defined(SCOUT)
#define HAVE_freeMemory (1)
    return heapFreeBytes ();
#endif /* SCOUT */
#if defined(linux)
#define HAVE_freeMemory (1)
    return getFreeMemory();
#endif /* linux */
#if ! defined(HAVE_freeMemory)
    struct rlimit lims;
    int heapsize = GC_get_heap_size();

    getrlimit(RLIMIT_DATA, &lims);
    return lims.rlim_cur - heapsize;
#endif /* ! HAVE_freeMemory */
#undef HAVE_freeMemory
}

/* java/lang/Runtime totalMemory ()J */
Long totalMemory__8OtkB(Object Harg1)
/*ARGSUSED*/
{
#undef HAVE_totalMemory
#if defined(__CYGWIN32__)
#define HAVE_totalMemory (1)
    return 10 * 1024 * 1024; /* XXX */
#endif /* __CYGWIN32__ */
#if defined(SCOUT)
#define HAVE_totalMemory (1)
    return GC_get_heap_size() + heapFreeBytes();
#endif /* SCOUT */
#if defined(linux)
#define HAVE_totalMemory (1)
    return (getFreeMemory() + GC_get_heap_size());
#endif /* linux */
#if ! defined(HAVE_totalMemory) 
    struct rlimit lims;

    getrlimit(RLIMIT_DATA, &lims);
    return lims.rlim_cur;
#endif /* ! HAVE_totalMemory */
#undef HAVE_totalMemory
}

/* java/lang/Runtime gc ()V */
Void gc__tAMwu(Object Harg1)
/*ARGSUSED*/
{
    GC_gcollect();
}

/* java/lang/Runtime runFinalization ()V */
Void runFinalization__WV7ck(Object Harg1)
/*ARGSUSED*/
{
    GC_invoke_finalizers();
    run_some_finalizers(mythread(), 0);
}

/* java/lang/Runtime traceInstructions (Z)V */
Void traceInstructions_z_x0Ew4(Object Harg1, Boolean arg2)
/*ARGSUSED*/
{
    /* 
     * "the virtual machine may ignore this request if it does not support
     * this feature"  -java api vol I, pg 82
     */
}

/* java/lang/Runtime traceMethodCalls (Z)V */
Void traceMethodCalls_z_aBRgg(Object Harg1, Boolean arg2)
/*ARGSUSED*/
{
    /* 
     * "the virtual machine may ignore this request if it does not support
     * this feature"  -java api vol I, pg 82
     */
}

/* synchronized java/lang/Runtime initializeLinkerInternal ()Ljava/lang/String; */
Object sy_initializeLinkerInternal__tobNT(Object Harg1)
/*ARGSUSED*/
{
    char *libpath;
#ifdef SCOUT
    libpath = "";
#else /* SCOUT */
    libpath = getenv("LD_LIBRARY_PATH");
    if (libpath == 0)
	libpath = ":/usr/lib";
#endif /* SCOUT */
    return javastring(libpath);
}

/* java/lang/Runtime buildLibName (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */
Object buildLibName_SS_lOXXd(Object Harg1, Object Harg2, Object Harg3)
/*ARGSUSED*/
{
    struct in_java_lang_String *pathname = Harg2;
    struct in_java_lang_String *libname = Harg3;

    struct in_java_lang_String *filename;

    /* concatenate the pathname, the file separator, 
     * "lib", the libname, and ".so" */
    filename = pathname->class->M.concat_S_WOS31.f(pathname,
						   javastring(FILE_SEPARATOR "lib"));
    filename = filename->class->M.concat_S_WOS31.f(filename, libname);
    filename = filename->class->M.concat_S_WOS31.f(filename, javastring(".so"));

    return filename;
}

/* java/lang/Runtime loadFileInternal (Ljava/lang/String;)Z */
Boolean loadFileInternal_S_K1q7k(Object Harg1, Object Harg2)
/*ARGSUSED*/
{
    /* For now, we ignore whether we actually
     * found the library, since we don't have some of the 
     * library names that systems ask for.  TODO */
    (void)load_native_library(Harg2);
    return 1;
}

