diff --git a/core/c/README b/core/c/README new file mode 100644 index 0000000000000000000000000000000000000000..229a8a83de99265bd9683cef4373c6b277235d72 --- /dev/null +++ b/core/c/README @@ -0,0 +1,9 @@ +Prior to building the jbigi library, you will need to fetch the GMP source +from http://www.swox.com/gmp/, saving it to jbigi/gmp-4.1.3.tar.bz2 (it will +be unpacked and built as necessary). + +To build the native jbigi and jcpuid libraries for the current host CPU, +simply run sh build.sh and the results will be packaged up into jbigi.jar + +To build the native jbigi libraries for all supported CPUs (on the current OS), +go into jbigi/ and run build-all.sh (the results will be under jbigi/lib/) diff --git a/core/c/build.sh b/core/c/build.sh index 233a795064129b9ff87faf1eeb2b501d83aa097a..ca2826dcf2648fd2065b6984e15fae6404e6dcad 100644 --- a/core/c/build.sh +++ b/core/c/build.sh @@ -1,40 +1,14 @@ -#!/bin/sh -# linux settings: -CC="gcc" -ANT="ant" -JAVA="java" +#/bin/sh -COMPILEFLAGS="-fPIC -Wall" -LINKFLAGS="-shared -Wl,-soname,libjbigi.so" +(cd jcpuid ; sh build.sh ; cd ..) +(cd jbigi ; sh build.sh ; cd ..) -INCLUDES="-Iinclude -I$JAVA_HOME/include -I$JAVA_HOME/include/linux" -INCLUDELIBS="-lgmp" -STATICLIBS="" +mkdir -p t/freenet/support/CPUInformation/ +cp jcpuid/lib/freenet/support/CPUInformation/*jcpuid-* t/freenet/support/CPUInformation/ -LIBFILE="libjbigi.so" +mkdir -p t/net/i2p/util/ +cp jbigi/lib/net/i2p/util/*jbigi-* t/net/i2p/util/ -# jrandom's mingw setup: -#COMPILEFLAGS="-Wall" -#INCLUDES="-Iinclude -Ic:/software/j2sdk1.4.2/include/win32/ -Ic:/software/j2sdk1.4.2/include/ -Ic:/dev/gmp-4.1.2/" -#LINKFLAGS="-shared -Wl,--kill-at" -#LIBFILE="jbigi.dll" -#INCLUDELIBS="" -#STATICLIBS="libgmp.a" +(cd t ; jar cf ../jbigi.jar . ; cd ..) -echo "Compiling C code..." -rm -f jbigi.o $LIBFILE -$CC -c $COMPILEFLAGS $INCLUDES src/jbigi.c -$CC $LINKFLAGS $INCLUDES $INCLUDELIBS -o $LIBFILE jbigi.o $STATICLIBS - -echo "" -echo "Doing an ant build..." -(cd ../java/ ; $ANT build) - -echo "" -echo "Built, now testing... This will take a while." -LD_LIBRARY_PATH=. $JAVA -cp ../java/build/i2p.jar -DloggerConfigLocation=../../installer/java/src/logger.config.template net.i2p.util.NativeBigInteger - - -echo "" -echo "" -echo "Test complete. Please review the lines 'native run time:', 'java run time:', and 'native = '" +echo "Native code built into jbigi.jar" diff --git a/core/c/jbigi/README b/core/c/jbigi/README new file mode 100644 index 0000000000000000000000000000000000000000..b8417be99acd98ee4db6cc823dfd1de3644124a9 --- /dev/null +++ b/core/c/jbigi/README @@ -0,0 +1,13 @@ +***net.i2p.util.NativeBigInteger, native part of the code**** + +Execute the build.sh script to produce jbigi library files optimized for a number of different CPU-types. + +TODO: What is jbigi +TODO: Document generated folder structure +TODO: Instructions for adding the libraries to a jar + +Linux-specific information: +Some linux distributions comes bundled with GMP. There is currently no out-of-the-box support for this in the current build-scripts. + +Windows-specific information: +The best way of building the jbigi dll's is to install Mingw {URL} and msys {URL}. The combination of these two should be able to run the included build-scripts without modifications. \ No newline at end of file diff --git a/core/c/jbigi/build-all.sh b/core/c/jbigi/build-all.sh new file mode 100644 index 0000000000000000000000000000000000000000..0b1502724889ce2d8e8b57d1f4641d1b4b2685b2 --- /dev/null +++ b/core/c/jbigi/build-all.sh @@ -0,0 +1,40 @@ +#/bin/sh + +case `uname -sr` in +MINGW*) + echo "Building windows .dlls for all architectures";; +Linux*) + echo "Building linux .sos for all architectures";; +FreeBSD*) + echo "Building freebsd .sos for all architectures";; +*) + echo "Unsupported build environment" + exit;; +esac + +echo "Extracting GMP..." +tar -xzf gmp-4.1.3.tar.gz +echo "Building..." +mkdir bin +mkdir lib +mkdir lib/net +mkdir lib/net/i2p +mkdir lib/net/i2p/util +for x in none pentium pentiummmx pentium2 pentium3 pentium4 k6 k62 k63 athlon +do + mkdir bin/$x + cd bin/$x + ../../gmp-4.1.3/configure --build=$x + make + sh ../../build_jbigi.sh static + case `uname -sr` in + MINGW*) + cp jbigi.dll ../../lib/net/i2p/util/jbigi-windows-$x.dll;; + Linux*) + cp libjbigi.so ../../lib/net/i2p/util/libjbigi-linux-$x.so;; + FreeBSD*) + cp libjbigi.so ../../lib/net/i2p/util/libjbigi-freebsd-$x.so;; + esac + cd .. + cd .. +done diff --git a/core/c/jbigi/build.sh b/core/c/jbigi/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..1a6ca48a349fe3e56d8f7e056863b29a15cf1697 --- /dev/null +++ b/core/c/jbigi/build.sh @@ -0,0 +1,41 @@ +#/bin/sh + +case `uname -sr` in +MINGW*) + echo "Building windows .dll's";; +CYGWIN*) + echo "Building windows .dll's";; +Linux*) + echo "Building linux .so's";; +FreeBSD*) + echo "Building freebsd .so's";; +*) + echo "Unsupported build environment" + exit;; +esac + +echo "Extracting GMP..." +tar -xzf gmp-4.1.3.tar.gz +echo "Building..." +mkdir bin +mkdir lib +mkdir lib/net +mkdir lib/net/i2p +mkdir lib/net/i2p/util +mkdir bin/local +cd bin/local +../../gmp-4.1.3/configure +make +sh ../../build_jbigi.sh static +case `uname -sr` in +MINGW*) + cp jbigi.dll ../../lib/net/i2p/util/jbigi-windows-x86.dll;; +CYGWIN*) + cp jbigi.dll ../../lib/net/i2p/util/jbigi-windows-x86.dll;; +Linux*) + cp libjbigi.so ../../lib/net/i2p/util/libjbigi-linux-x86.so;; +FreeBSD*) + cp libjbigi.so ../../lib/net/i2p/util/libjbigi-freebsd-x86.so;; +esac +cd .. +cd .. diff --git a/core/c/jbigi/build_jbigi.sh b/core/c/jbigi/build_jbigi.sh new file mode 100644 index 0000000000000000000000000000000000000000..54b0a36739eee3a4ec807370e02a0edb28c6b45a --- /dev/null +++ b/core/c/jbigi/build_jbigi.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# When executed in Mingw: Produces an jbigi.dll +# When executed in Linux: Produces an libjbigi.so + +CC="gcc" + +case `uname -sr` in +MINGW*) + JAVA_HOME="c:/software/j2sdk1.4.2_05" + COMPILEFLAGS="-Wall" + INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include/win32/ -I$JAVA_HOME/include/" + LINKFLAGS="-shared -Wl,--kill-at" + LIBFILE="jbigi.dll";; +CYGWIN*) + JAVA_HOME="c:/software/j2sdk1.4.2_05" + COMPILEFLAGS="-Wall -mno-cygwin" + INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include/win32/ -I$JAVA_HOME/include/" + LINKFLAGS="-shared -Wl,--kill-at" + LIBFILE="jbigi.dll";; +*) + COMPILEFLAGS="-fPIC -Wall" + INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/linux" + LINKFLAGS="-shared -Wl,-soname,libjbigi.so" + LIBFILE="libjbigi.so";; +esac + +#To link dynamically to GMP (use libgmp.so or gmp.lib), uncomment the first line below +#To link statically to GMP, uncomment the second line below +if test $1 = "dynamic" +then + echo "Building jbigi lib that is dynamically linked to GMP" + LIBPATH="-L.libs" + INCLUDELIBS="-lgmp" +else + echo "Building jbigi lib that is statically linked to GMP" + STATICLIBS=".libs/libgmp.a" +fi + +echo "Compiling C code..." +rm -f jbigi.o $LIBFILE +$CC -c $COMPILEFLAGS $INCLUDES ../../jbigi/src/jbigi.c +$CC $LINKFLAGS $INCLUDES $INCLUDELIBS -o $LIBFILE jbigi.o $STATICLIBS diff --git a/core/c/jbigi/jbigi/include/jbigi.h b/core/c/jbigi/jbigi/include/jbigi.h new file mode 100644 index 0000000000000000000000000000000000000000..1b1c1c26314604289f5c7c7e4b58cf43ce3c243c --- /dev/null +++ b/core/c/jbigi/jbigi/include/jbigi.h @@ -0,0 +1,62 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class net_i2p_util_NativeBigInteger */ + +#ifndef _Included_net_i2p_util_NativeBigInteger +#define _Included_net_i2p_util_NativeBigInteger +#ifdef __cplusplus +extern "C" { +#endif +#undef net_i2p_util_NativeBigInteger_serialVersionUID +#define net_i2p_util_NativeBigInteger_serialVersionUID -8742448824652078965i64 +#undef net_i2p_util_NativeBigInteger_LONG_MASK +#define net_i2p_util_NativeBigInteger_LONG_MASK 4294967295i64 +/* Inaccessible static: bitsPerDigit */ +#undef net_i2p_util_NativeBigInteger_SMALL_PRIME_THRESHOLD +#define net_i2p_util_NativeBigInteger_SMALL_PRIME_THRESHOLD 95L +/* Inaccessible static: SMALL_PRIME_PRODUCT */ +#undef net_i2p_util_NativeBigInteger_MAX_CONSTANT +#define net_i2p_util_NativeBigInteger_MAX_CONSTANT 16L +/* Inaccessible static: posConst */ +/* Inaccessible static: negConst */ +/* Inaccessible static: ZERO */ +/* Inaccessible static: ONE */ +/* Inaccessible static: TWO */ +/* Inaccessible static: bnExpModThreshTable */ +/* Inaccessible static: trailingZeroTable */ +/* Inaccessible static: zeros */ +/* Inaccessible static: digitsPerLong */ +/* Inaccessible static: longRadix */ +/* Inaccessible static: digitsPerInt */ +/* Inaccessible static: intRadix */ +#undef net_i2p_util_NativeBigInteger_serialVersionUID +#define net_i2p_util_NativeBigInteger_serialVersionUID -8287574255936472291i64 +/* Inaccessible static: serialPersistentFields */ +/* Inaccessible static: array_00024B */ +/* Inaccessible static: _nativeOk */ +#undef net_i2p_util_NativeBigInteger__doLog +#define net_i2p_util_NativeBigInteger__doLog 1L +/* Inaccessible static: DEFAULT_REF_FILENAME */ +/* Inaccessible static: _sampleGenerator */ +/* Inaccessible static: _samplePrime */ +/* Inaccessible static: class_000240 */ +/* + * Class: net_i2p_util_NativeBigInteger + * Method: nativeModPow + * Signature: ([B[B[B)[B + */ +JNIEXPORT jbyteArray JNICALL Java_net_i2p_util_NativeBigInteger_nativeModPow + (JNIEnv *, jclass, jbyteArray, jbyteArray, jbyteArray); + +/* + * Class: net_i2p_util_NativeBigInteger + * Method: nativeDoubleValue + * Signature: ([B)D + */ +JNIEXPORT jdouble JNICALL Java_net_i2p_util_NativeBigInteger_nativeDoubleValue + (JNIEnv *, jclass, jbyteArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/c/jbigi/jbigi/src/jbigi.c b/core/c/jbigi/jbigi/src/jbigi.c new file mode 100644 index 0000000000000000000000000000000000000000..a0aea5b94d665392bcb9340e332ed88f5b362bf8 --- /dev/null +++ b/core/c/jbigi/jbigi/src/jbigi.c @@ -0,0 +1,178 @@ +#include <stdio.h> +#include <gmp.h> +#include "jbigi.h" + +/******** prototypes */ + +void convert_j2mp(JNIEnv* env, jbyteArray jvalue, mpz_t* mvalue); +void convert_mp2j(JNIEnv* env, mpz_t mvalue, jbyteArray* jvalue); + + +/***************************************** + *****Native method implementations******* + *****************************************/ + +/******** nativeModPow() */ +/* + * Class: net_i2p_util_NativeBigInteger + * Method: nativeModPow + * Signature: ([B[B[B)[B + * + * From the javadoc: + * + * calculate (base ^ exponent) % modulus. + * @param curVal big endian twos complement representation of the base (but it must be positive) + * @param exponent big endian twos complement representation of the exponent + * @param modulus big endian twos complement representation of the modulus + * @return big endian twos complement representation of (base ^ exponent) % modulus + */ + +JNIEXPORT jbyteArray JNICALL Java_net_i2p_util_NativeBigInteger_nativeModPow + (JNIEnv* env, jclass cls, jbyteArray jbase, jbyteArray jexp, jbyteArray jmod) { + /* 1) Convert base, exponent, modulus into the format libgmp understands + * 2) Call libgmp's modPow. + * 3) Convert libgmp's result into a big endian twos complement number. + */ + + mpz_t mbase; + mpz_t mexp; + mpz_t mmod; + jbyteArray jresult; + + convert_j2mp(env, jbase, &mbase); + convert_j2mp(env, jexp, &mexp); + convert_j2mp(env, jmod, &mmod); + + /* Perform the actual powmod. We use mmod for the result because it is + * always at least as big as the result. + */ + mpz_powm(mmod, mbase, mexp, mmod); + + convert_mp2j(env, mmod, &jresult); + + mpz_clear(mbase); + mpz_clear(mexp); + mpz_clear(mmod); + + return jresult; +} + +/******** nativeDoubleValue() */ +/* + * Class: net_i2p_util_NativeBigInteger + * Method: nativeDoubleValue + * Signature: ([B)D + * + * From the Javadoc: + * + * Converts a BigInteger byte-array to a 'double' + * @param ba Big endian twos complement representation of the BigInteger to convert to a double + * @return The plain double-value represented by 'ba' + */ +JNIEXPORT jdouble JNICALL Java_net_i2p_util_NativeBigInteger_nativeDoubleValue +(JNIEnv * env, jclass cls, jbyteArray jba){ + /* 1) Convert the bytearray BigInteger value into the format libgmp understands + * 2) Call libgmp's mpz_get_d. + * 3) Convert libgmp's result into a big endian twos complement number. + */ + mpz_t mval; + jdouble retval; + convert_j2mp(env, jba, &mval); + + retval = mpz_get_d(mval); + mpz_clear(mval); + return retval; +} + +/****************************** + *****Conversion methods******* + ******************************/ + +/*Luckily we can use GMP's mpz_import() and mpz_export() functions to convert from/to + *BigInteger.toByteArray() representation. + */ + +/******** convert_j2mp() */ +/* + * Initializes the GMP value with enough preallocated size, and converts the + * Java value into the GMP value. The value that mvalue points to should be + * uninitialized + */ + +void convert_j2mp(JNIEnv* env, jbyteArray jvalue, mpz_t* mvalue) +{ + jsize size; + jbyte* jbuffer; + //int sign; + + size = (*env)->GetArrayLength(env, jvalue); + jbuffer = (*env)->GetByteArrayElements(env, jvalue, NULL); + + mpz_init2(*mvalue, sizeof(jbyte) * 8 * size); //preallocate the size + + /* void mpz_import( + * mpz_t rop, size_t count, int order, int size, int endian, + * size_t nails, const void *op); + * + * order = 1 + * order can be 1 for most significant word first or -1 for least + * significant first. + * endian = 1 + * Within each word endian can be 1 for most significant byte first, + * -1 for least significant first. + * nails = 0 + * The most significant nails bits of each word are skipped, this can + * be 0 to use the full words. + */ + mpz_import(*mvalue, size, 1, sizeof(jbyte), 1, 0, (void*)jbuffer); + /*Uncomment this to support negative integer values, + not tested though.. + sign = jbuffer[0] < 0?-1:1; + if(sign == -1) + mpz_neg(*mvalue,*mvalue); + */ + (*env)->ReleaseByteArrayElements(env, jvalue, jbuffer, JNI_ABORT); +} + +/******** convert_mp2j() */ +/* + * Converts the GMP value into the Java value; Doesn't do anything else. + * Pads the resulting jbyte array with 0, so the twos complement value is always + * positive. + */ + +void convert_mp2j(JNIEnv* env, mpz_t mvalue, jbyteArray* jvalue) +{ + jsize size; + jbyte* buffer; + jboolean copy; + //int i; + + copy = JNI_FALSE; + + /* sizeinbase() + 7 => Ceil division */ + size = (mpz_sizeinbase(mvalue, 2) + 7) / 8 + sizeof(jbyte); + *jvalue = (*env)->NewByteArray(env, size); + + buffer = (*env)->GetByteArrayElements(env, *jvalue, ©); + buffer[0] = 0x00; + //Uncomment the comments below to support negative integer values, + //not very well-tested though.. + //if(mpz_sgn(mvalue) >=0){ + mpz_export((void*)&buffer[1], &size, 1, sizeof(jbyte), 1, 0, mvalue); + //}else{ + // mpz_add_ui(mvalue,mvalue,1); + // mpz_export((void*)&buffer[1], &size, 1, sizeof(jbyte), 1, 0, mvalue); + // for(i =0;i<=size;i++){ //This could be done more effectively + // buffer[i]=~buffer[i]; + // } + //} + + /* mode has (supposedly) no effect if elems is not a copy of the + * elements in array + */ + (*env)->ReleaseByteArrayElements(env, *jvalue, buffer, 0); + //mode has (supposedly) no effect if elems is not a copy of the elements in array +} + +/******** eof */ diff --git a/core/c/jcpuid/build.sh b/core/c/jcpuid/build.sh new file mode 100644 index 0000000000000000000000000000000000000000..72ac5dec6ce1e1ecdb00243dc3cc90b4c5325b3d --- /dev/null +++ b/core/c/jcpuid/build.sh @@ -0,0 +1,52 @@ +#/bin/sh + +case `uname -sr` in +MINGW*) + echo "Building windows .dll's";; +CYGWIN*) + echo "Building windows .dll's";; +Linux*) + echo "Building linux .so's";; +FreeBSD*) + echo "Building freebsd .so's";; +*) + echo "Unsupported build environment" + exit;; +esac + +rm -rf lib +mkdir lib +mkdir lib/freenet +mkdir lib/freenet/support +mkdir lib/freenet/support/CPUInformation + +CPP="g++" + +case `uname -sr` in +MINGW*) + JAVA_HOME="/c/software/j2sdk1.4.2_05" + COMPILEFLAGS="-Wall" + INCLUDES="-I. -Iinclude -I$JAVA_HOME/include/ -I$JAVA_HOME/include/win32/" + LINKFLAGS="-shared -static -static-libgcc -Wl,--kill-at" + LIBFILE="lib/freenet/support/CPUInformation/jcpuid-x86-windows.dll";; +FreeBSD*) + COMPILEFLAGS="-Wall" + INCLUDES="-I. -Iinclude -I$JAVA_HOME/include/ -I$JAVA_HOME/include/freebsd/" + LINKFLAGS="-shared -static -static-libgcc -Wl,-soname,libjcpuid-x86-freebsd.so" + LIBFILE="lib/freenet/support/CPUInformation/libjcpuid-x86-freebsd.so";; +Linux*) + COMPILEFLAGS="-fPIC -Wall" + INCLUDES="-I. -Iinclude -I$JAVA_HOME/include -I$JAVA_HOME/include/linux" + LINKFLAGS="-shared -static -static-libgcc -Wl,-soname,libjcpuid-x86-linux.so" + LIBFILE="lib/freenet/support/CPUInformation/libjcpuid-x86-linux.so";; +esac + +echo "Compiling C code..." +rm -f $LIBFILE +$CPP $LINKFLAGS $INCLUDES src/*.cpp -o $LIBFILE +strip $LIBFILE +echo Built $LIBFILE + +#g++ -shared -static -static-libgcc -Iinclude -I$JAVA_HOME/include \ +# -I$JAVA_HOME/include/linux src/*.cpp \ +# -o lib/freenet/support/CPUInformation/libjcpuid-x86-linux.so diff --git a/core/c/jcpuid/include/jcpuid.h b/core/c/jcpuid/include/jcpuid.h new file mode 100644 index 0000000000000000000000000000000000000000..ff8cbbe28c03e14db0e657d6eb47cd4a13e2c67e --- /dev/null +++ b/core/c/jcpuid/include/jcpuid.h @@ -0,0 +1,21 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include <jni.h> +/* Header for class freenet_support_CPUInformation_CPUID */ + +#ifndef _Included_freenet_support_CPUInformation_CPUID +#define _Included_freenet_support_CPUInformation_CPUID +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: freenet_support_CPUInformation_CPUID + * Method: doCPUID + * Signature: (I)Lfreenet/support/CPUInformation/CPUID$CPUIDResult; + */ +JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID + (JNIEnv *, jclass, jint); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/c/jcpuid/msvc/IMPORTANT.txt b/core/c/jcpuid/msvc/IMPORTANT.txt new file mode 100644 index 0000000000000000000000000000000000000000..0b9bdb00822ff2f7edd5c75e90737bde2c41732f --- /dev/null +++ b/core/c/jcpuid/msvc/IMPORTANT.txt @@ -0,0 +1,2 @@ +You will need to rename the 'cpuinformation' par of the output folder '..\lib\freenet\support\cpuinformation' to 'CPUInformation' before importing the files to a .jar. +Unfortunately MSVC doesn't respect the casing of the entered output folder. \ No newline at end of file diff --git a/core/c/jcpuid/msvc/jcpuid.sln b/core/c/jcpuid/msvc/jcpuid.sln new file mode 100644 index 0000000000000000000000000000000000000000..d06efb411cb6f5804a37463f310225c79117bb7a --- /dev/null +++ b/core/c/jcpuid/msvc/jcpuid.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jcpuid", "jcpuid.vcproj", "{161B6AD9-3825-4BA5-893D-D90B09846849}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(DPCodeReviewSolutionGUID) = preSolution + DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} + EndGlobalSection + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {161B6AD9-3825-4BA5-893D-D90B09846849}.Debug.ActiveCfg = Debug|Win32 + {161B6AD9-3825-4BA5-893D-D90B09846849}.Debug.Build.0 = Debug|Win32 + {161B6AD9-3825-4BA5-893D-D90B09846849}.Release.ActiveCfg = Release|Win32 + {161B6AD9-3825-4BA5-893D-D90B09846849}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/core/c/jcpuid/msvc/jcpuid.suo b/core/c/jcpuid/msvc/jcpuid.suo new file mode 100644 index 0000000000000000000000000000000000000000..5ce68a32238298f8c2eb94e334f60061dcb0a6d9 Binary files /dev/null and b/core/c/jcpuid/msvc/jcpuid.suo differ diff --git a/core/c/jcpuid/msvc/jcpuid.vcproj b/core/c/jcpuid/msvc/jcpuid.vcproj new file mode 100644 index 0000000000000000000000000000000000000000..1b1c6b1f6d8c9aac1f7a62871136111053285368 --- /dev/null +++ b/core/c/jcpuid/msvc/jcpuid.vcproj @@ -0,0 +1,139 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="jcpuid" + ProjectGUID="{161B6AD9-3825-4BA5-893D-D90B09846849}" + RootNamespace="jcpuid" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="..\lib\freenet\support\CPUInformation" + IntermediateDirectory="Debug" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;jcpuid_EXPORTS" + MinimalRebuild="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/jcpuid-x86-windows.dll" + LinkIncremental="2" + GenerateDebugInformation="TRUE" + ProgramDatabaseFile="$(OutDir)/jcpuid.pdb" + SubSystem="2" + ImportLibrary="$(OutDir)/jcpuid.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="..\lib\freenet\support\CPUInformation" + IntermediateDirectory="Release" + ConfigurationType="2" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(SolutionDir)\..\include"" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;jcpuid_EXPORTS" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="3" + Detect64BitPortabilityProblems="TRUE" + DebugInformationFormat="3"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLinkerTool" + OutputFile="$(OutDir)/jcpuid-x86-windows.dll" + LinkIncremental="1" + GenerateDebugInformation="TRUE" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + ImportLibrary="$(OutDir)/jcpuid.lib" + TargetMachine="1"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCWebDeploymentTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> + <File + RelativePath="..\src\jcpuid.cpp"> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> + <File + RelativePath="..\include\jcpuid.h"> + </File> + </Filter> + <Filter + Name="Resource Files" + Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/core/c/jcpuid/src/jcpuid.cpp b/core/c/jcpuid/src/jcpuid.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e3ddba9c451343344b051264a5a365135521e26e --- /dev/null +++ b/core/c/jcpuid/src/jcpuid.cpp @@ -0,0 +1,35 @@ +#include "jcpuid.h" + +//Executes the indicated subfunction of the CPUID operation +JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID + (JNIEnv * env, jclass cls, jint iFunction) +{ + int a,b,c,d; + jclass clsResult = env->FindClass ("freenet/support/CPUInformation/CPUID$CPUIDResult"); + jmethodID constructor = env->GetMethodID(clsResult,"<init>","(IIII)V" ); + #ifdef _MSC_VER + //Use MSVC assembler notation + _asm + { + mov eax, iFunction + cpuid + mov a, eax + mov b, ebx + mov c, ecx + mov d, edx + } + #else + //Use GCC assembler notation + asm + ( + "cpuid" + : "=a" (a), + "=b" (b), + "=c"(c), + "=d"(d) + :"a"(iFunction) + ); + #endif + return env->NewObject(clsResult,constructor,a,b,c,d); +} + diff --git a/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..f4fc2320939baea748d7e7236b238df5eefae080 --- /dev/null +++ b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java @@ -0,0 +1,39 @@ +/* + * Created on Jul 17, 2004 + * + */ +package freenet.support.CPUInformation; + +/** + * @author Iakin + * An interface for classes that provide lowlevel information about AMD CPU's + * + * free (adj.): unencumbered; not under the control of others + * Written by Iakin in 2004 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + */ +public interface AMDCPUInfo extends CPUInfo { + /** + * @return true iff the CPU present in the machine is at least an 'k6' CPU + */ + public boolean IsK6Compatible(); + /** + * @return true iff the CPU present in the machine is at least an 'k6-2' CPU + */ + public boolean IsK6_2_Compatible(); + /** + * @return true iff the CPU present in the machine is at least an 'k6-3' CPU + */ + public boolean IsK6_3_Compatible(); + + /** + * @return true iff the CPU present in the machine is at least an 'k7' CPU (Atlhon, Duron etc. and better) + */ + public boolean IsAthlonCompatible(); + /** + * @return true iff the CPU present in the machine is at least an 'k8' CPU (Atlhon 64, Opteron etc. and better) + */ + public boolean IsAthlon64Compatible(); +} diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java new file mode 100644 index 0000000000000000000000000000000000000000..51f3b1b9ced6a6ea33dd0c67f2ccb5b21e7927f1 --- /dev/null +++ b/core/java/src/freenet/support/CPUInformation/CPUID.java @@ -0,0 +1,553 @@ +/* + * Created on Jul 14, 2004 + */ +package freenet.support.CPUInformation; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +/** + * @author Iakin + * A class for retrieveing details about the CPU using the CPUID assembly instruction. + * A good resource for information about the CPUID instruction can be found here: + * http://www.paradicesoftware.com/specs/cpuid/index.htm + * + * free (adj.): unencumbered; not under the control of others + * Written by Iakin in 2004 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. +*/ + +public class CPUID { + + /** did we load the native lib correctly? */ + private static boolean _nativeOk = false; + + /** + * do we want to dump some basic success/failure info to stderr during + * initialization? this would otherwise use the Log component, but this makes + * it easier for other systems to reuse this class + */ + private static final boolean _doLog = true; + + //.matches() is a java 1.4+ addition, using a simplified version for 1.3+ + //private static final boolean isX86 = System.getProperty("os.arch").toLowerCase().matches("i?[x0-9]86(_64)?"); + private static final boolean isX86 = (-1 != System.getProperty("os.arch").indexOf("86")); + + static + { + loadNative(); + } + + //A class that can (amongst other things I assume) represent the state of the + //different CPU registers after a call to the CPUID assembly method + protected static class CPUIDResult { + final int EAX; + final int EBX; + final int ECX; + final int EDX; + CPUIDResult(int EAX,int EBX,int ECX, int EDX) + { + this.EAX = EAX; + this.EBX = EBX; + this.ECX = ECX; + this.EDX = EDX; + } + } + + /**Calls the indicated CPUID function and returns the result of the execution + * + * @param iFunction The CPUID function to call, should be 0 or larger + * @return The contents of the CPU registers after the call to the CPUID function + */ + private static native CPUIDResult doCPUID(int iFunction); + + private static String getCPUVendorID() + { + CPUIDResult c = doCPUID(0); + StringBuffer sb= new StringBuffer(13); + sb.append((char)( c.EBX & 0xFF)); + sb.append((char)((c.EBX >> 8) & 0xFF)); + sb.append((char)((c.EBX >> 16) & 0xFF)); + sb.append((char)((c.EBX >> 24) & 0xFF)); + + sb.append((char)( c.EDX & 0xFF)); + sb.append((char)((c.EDX >> 8) & 0xFF)); + sb.append((char)((c.EDX >> 16) & 0xFF)); + sb.append((char)((c.EDX >> 24) & 0xFF)); + + sb.append((char)( c.ECX & 0xFF)); + sb.append((char)((c.ECX >> 8) & 0xFF)); + sb.append((char)((c.ECX >> 16) & 0xFF)); + sb.append((char)((c.ECX >> 24) & 0xFF)); + + return sb.toString(); + } + private static int getCPUFamily() + { + CPUIDResult c = doCPUID(1); + return (c.EAX >> 8) & 0xf; + } + private static int getCPUModel() + { + CPUIDResult c = doCPUID(1); + return (c.EAX >> 4) & 0xf; + } + private static int getCPUExtendedModel() + { + CPUIDResult c = doCPUID(1); + return (c.EAX >> 16) & 0xf; + } + private static int getCPUType() + { + CPUIDResult c = doCPUID(1); + return (c.EAX >> 12) & 0xf; + } + private static int getCPUExtendedFamily() + { + CPUIDResult c = doCPUID(1); + return (c.EAX >> 20) & 0xff; + } + private static int getCPUStepping() + { + CPUIDResult c = doCPUID(1); + return c.EAX & 0xf; + } + private static int getCPUFlags() + { + CPUIDResult c = doCPUID(1); + return c.EDX; + } + + //Returns a CPUInfo item for the current type of CPU + //If I could I would declare this method in a interface named + //CPUInfoProvider and implement that interface in this class. + //This would make it easier for other people to understand that there + //is nothing preventing them from coding up new providers, probably using + //other detection methods than the x86-only CPUID instruction + public static CPUInfo getInfo() throws UnknownCPUException + { + if(!_nativeOk) + throw new UnknownCPUException("Failed to read CPU information from the system. Please verify the existence of the jcpuid dll/so."); + if(!isX86) + throw new UnknownCPUException("Failed to read CPU information from the system. The CPUID instruction exists on x86 CPU's only"); + if(getCPUVendorID().equals("AuthenticAMD")) + return new AMDInfoImpl(); + if(getCPUVendorID().equals("GenuineIntel")) + return new IntelInfoImpl(); + throw new UnknownCPUException("Unknown CPU type: '"+getCPUVendorID()+"'"); + } + + protected abstract static class CPUIDCPUInfo + { + public String getVendor() + { + return getCPUVendorID(); + } + public boolean hasMMX(){ + return (getCPUFlags() & 0x800000) >0; //Bit 23 + } + public boolean hasSSE(){ + return (getCPUFlags() & 0x2000000) >0; //Bit 25 + } + public boolean hasSSE2(){ + return (getCPUFlags() & 0x4000000) >0; //Bit 26 + } + } + protected static class AMDInfoImpl extends CPUIDCPUInfo implements AMDCPUInfo + { + public boolean IsK6Compatible() + { + return getCPUFamily() >= 5 && getCPUModel() >= 6; + } + public boolean IsK6_2_Compatible() + { + return getCPUFamily() >= 5 && getCPUModel() >= 8; + } + public boolean IsK6_3_Compatible() + { + return getCPUFamily() >= 5 && getCPUModel() >= 9; + } + public boolean IsAthlonCompatible() + { + return getCPUFamily() >= 6; + } + public boolean IsAthlon64Compatible() + { + return getCPUFamily() == 15 && getCPUExtendedFamily() == 0; + } + + public String getCPUModelString() throws UnknownCPUException + { + if(getCPUFamily() == 4){ + switch(getCPUModel()){ + case 3: + return "486 DX/2"; + case 7: + return "486 DX/2-WB"; + case 8: + return "486 DX/4"; + case 9: + return "486 DX/4-WB"; + case 14: + return "Am5x86-WT"; + case 15: + return "Am5x86-WB"; + } + } + if(getCPUFamily() == 5){ + switch(getCPUModel()){ + case 0: + return "K5/SSA5"; + case 1: + return "K5"; + case 2: + return "K5"; + case 3: + return "K5"; + case 6: + return "K6"; + case 7: + return "K6"; + case 8: + return "K6-2"; + case 9: + return "K6-3"; + case 13: + return "K6-2+ or K6-III+"; + } + } + if(getCPUFamily() == 6){ + switch(getCPUModel()){ + case 0: + return "Athlon (250 nm)"; + case 1: + return "Athlon (250 nm)"; + case 2: + return "Athlon (180 nm)"; + case 3: + return "Duron"; + case 4: + return "Athlon (Thunderbird)"; + case 6: + return "Athlon (Palamino)"; + case 7: + return "Duron (Morgan)"; + case 8: + return "Athlon (Thoroughbred)"; + case 10: + return "Athlon (Barton)"; + } + } + if(getCPUFamily() == 15){ + if(getCPUExtendedFamily() == 0){ + switch(getCPUModel()){ + case 4: + return "Athlon 64"; + case 5: + return "Athlon 64 FX Opteron"; + } + } + } + throw new UnknownCPUException("Unknown AMD CPU; Family="+getCPUFamily()+", Model="+getCPUModel()); + } + } + + protected static class IntelInfoImpl extends CPUIDCPUInfo implements IntelCPUInfo + { + public boolean IsPentiumCompatible() + { + return getCPUFamily() >= 5; + } + public boolean IsPentiumMMXCompatible() + { + return IsPentium2Compatible() || (getCPUFamily() == 5 && (getCPUModel() ==4 || getCPUModel() == 8)); + } + public boolean IsPentium2Compatible() + { + return getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=3); + } + public boolean IsPentium3Compatible() + { + return getCPUFamily() > 6 || (getCPUFamily() == 6 && getCPUModel() >=7); + } + public boolean IsPentium4Compatible() + { + return getCPUFamily() >= 15; + } + public String getCPUModelString() throws UnknownCPUException { + if(getCPUFamily() == 4){ + switch(getCPUModel()){ + case 0: + return "486 DX-25/33"; + case 1: + return "486 DX-50"; + case 2: + return "486 SX"; + case 3: + return "486 DX/2"; + case 4: + return "486 SL"; + case 5: + return "486 SX/2"; + case 7: + return "486 DX/2-WB"; + case 8: + return "486 DX/4"; + case 9: + return "486 DX/4-WB"; + } + } + if(getCPUFamily() == 5){ + switch(getCPUModel()){ + case 0: + return "Pentium 60/66 A-step"; + case 1: + return "Pentium 60/66"; + case 2: + return "Pentium 75 - 200"; + case 3: + return "OverDrive PODP5V83"; + case 4: + return "Pentium MMX"; + case 7: + return "Mobile Pentium 75 - 200"; + case 8: + return "Mobile Pentium MMX"; + } + } + if(getCPUFamily() == 6){ + switch(getCPUModel()){ + case 0: + return "Pentium Pro A-step"; + case 1: + return "Pentium Pro"; + case 3: + return "Pentium II (Klamath)"; + case 5: + return "Pentium II (Deschutes), Celeron (Covington), Mobile Pentium II (Dixon)"; + case 6: + return "Mobile Pentium II, Celeron (Mendocino)"; + case 7: + return "Pentium III (Katmai)"; + case 8: + return "Pentium III (Coppermine), Celeron w/SSE"; + case 9: + return "Mobile Pentium III"; + case 10: + return "Pentium III Xeon (Cascades)"; + case 11: + return "Pentium III (130 nm)"; + } + } + if(getCPUFamily() == 7){ + switch(getCPUModel()){ + //Itanium.. TODO + } + } + if(getCPUFamily() == 15){ + if(getCPUExtendedFamily() == 0){ + switch(getCPUModel()){ + case 0: + return "Pentium IV (180 nm)"; + case 1: + return "Pentium IV (180 nm)"; + case 2: + return "Pentium IV (130 nm)"; + case 3: + return "Pentium IV (90 nm)"; + } + } + if(getCPUExtendedFamily() == 1){ + switch(getCPUModel()){ + // Itanium 2.. TODO + } + } + } + throw new UnknownCPUException("Unknown Intel CPU; Family="+getCPUFamily()+", Model="+getCPUModel()); + } + } + + public static void main(String args[]) + { + if(!_nativeOk){ + System.out.println("**Failed to retrieve CPUInfo. Please verify the existence of jcpuid dll/so**"); + } + System.out.println("**CPUInfo**"); + System.out.println("CPU Vendor: " + getCPUVendorID()); + System.out.println("CPU Family: " + getCPUFamily()); + System.out.println("CPU Model: " + getCPUModel()); + System.out.println("CPU Stepping: " + getCPUStepping()); + System.out.println("CPU Flags: " + getCPUFlags()); + + CPUInfo c = getInfo(); + System.out.println(" **More CPUInfo**"); + System.out.println(" CPU model string: " + c.getCPUModelString()); + System.out.println(" CPU has MMX: " + c.hasMMX()); + System.out.println(" CPU has SSE: " + c.hasSSE()); + System.out.println(" CPU has SSE2: " + c.hasSSE2()); + if(c instanceof IntelCPUInfo){ + System.out.println(" **Intel-info**"); + System.out.println(" Is pII-compatible: "+((IntelCPUInfo)c).IsPentium2Compatible()); + System.out.println(" Is pIII-compatible: "+((IntelCPUInfo)c).IsPentium3Compatible()); + System.out.println(" Is pIV-compatible: "+((IntelCPUInfo)c).IsPentium4Compatible()); + } + if(c instanceof AMDCPUInfo){ + System.out.println(" **AMD-info**"); + System.out.println(" Is Athlon-compatible: "+((AMDCPUInfo)c).IsAthlonCompatible()); + } + + } + + /** + * <p>Do whatever we can to load up the native library. + * If it can find a custom built jcpuid.dll / libjcpuid.so, it'll use that. Otherwise + * it'll try to look in the classpath for the correct library (see loadFromResource). + * If the user specifies -Djcpuid.enable=false it'll skip all of this.</p> + * + */ + private static final void loadNative() { + try{ + String wantedProp = System.getProperty("jcpuid.enable", "true"); + boolean wantNative = "true".equalsIgnoreCase(wantedProp); + if (wantNative) { + boolean loaded = loadFromResource(); + if (loaded) { + _nativeOk = true; + if (_doLog) + System.err.println("INFO: Native CPUID library '"+getResourceName()+"' loaded from resource"); + } else { + loaded = loadGeneric(); + if (loaded) { + _nativeOk = true; + if (_doLog) + System.err.println("INFO: Native CPUID library '"+getLibraryMiddlePart()+"' loaded from somewhere in the path"); + } else { + _nativeOk = false; + if (_doLog) + System.err.println("WARN: Native CPUID library jcpuid not loaded - will not be able to read CPU information using CPUID"); + } + } + } else { + if (_doLog) + System.err.println("INFO: Native CPUID library jcpuid not loaded - will not be able to read CPU information using CPUID"); + } + }catch(Exception e){ + if (_doLog) + System.err.println("INFO: Native CPUID library jcpuid not loaded, reason: '"+e.getMessage()+"' - will not be able to read CPU information using CPUID"); + } + } + + /** + * <p>Try loading it from an explictly built jcpuid.dll / libjcpuid.so</p> + * + * @return true if it was loaded successfully, else false + * + */ + private static final boolean loadGeneric() { + try { + System.loadLibrary(getLibraryMiddlePart()); + return true; + } catch (UnsatisfiedLinkError ule) { + return false; + } + } + + /** + * <p>Check all of the jars in the classpath for the jcpuid dll/so. + * This file should be stored in the resource in the same package as this class. + * + * <p>This is a pretty ugly hack, using the general technique illustrated by the + * onion FEC libraries. It works by pulling the resource, writing out the + * byte stream to a temporary file, loading the native library from that file, + * then deleting the file.</p> + * + * @return true if it was loaded successfully, else false + * + */ + private static final boolean loadFromResource() { + String resourceName = getResourceName(); + if (resourceName == null) return false; + URL resource = CPUID.class.getClassLoader().getResource(resourceName); + + if (resource == null) { + if (_doLog) + System.err.println("ERROR: Resource name [" + resourceName + "] was not found"); + return false; + } + + File outFile = null; + try { + InputStream libStream = resource.openStream(); + outFile = File.createTempFile("jcpuid", "lib.tmp"); + FileOutputStream fos = new FileOutputStream(outFile); + byte buf[] = new byte[4096*1024]; + while (true) { + int read = libStream.read(buf); + if (read < 0) break; + fos.write(buf, 0, read); + } + fos.close(); + System.load(outFile.getAbsolutePath());//System.load requires an absolute path to the lib + return true; + } catch (UnsatisfiedLinkError ule) { + if (_doLog) { + System.err.println("ERROR: The resource " + resourceName + + " was not a valid library for this platform"); + ule.printStackTrace(); + } + return false; + } catch (IOException ioe) { + if (_doLog) { + System.err.println("ERROR: Problem writing out the temporary native library data"); + ioe.printStackTrace(); + } + return false; + } finally { + if (outFile != null) { + outFile.deleteOnExit(); + } + } + } + + private static final String getResourceName() + { + String pname = CPUID.class.getPackage().getName().replace('.','/'); + return pname+"/"+getLibraryPrefix()+getLibraryMiddlePart()+"."+getLibrarySuffix(); + } + + private static final String getLibraryPrefix() + { + boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1; + if(isWindows) + return ""; + else + return "lib"; + } + + private static final String getLibraryMiddlePart(){ + boolean isWindows =(System.getProperty("os.name").toLowerCase().indexOf("windows") != -1); + boolean isLinux =(System.getProperty("os.name").toLowerCase().indexOf("linux") != -1); + boolean isFreebsd =(System.getProperty("os.name").toLowerCase().indexOf("freebsd") != -1); + if(isWindows) + return "jcpuid-x86-windows"; // The convention on Windows + if(isLinux) + return "jcpuid-x86-linux"; // The convention on linux... + if(isFreebsd) + return "jcpuid-x86-freebsd"; // The convention on freebsd... + throw new RuntimeException("Dont know jcpuid library name for os type '"+System.getProperty("os.name")+"'"); + } + + private static final String getLibrarySuffix() + { + boolean isWindows =System.getProperty("os.name").toLowerCase().indexOf("windows") != -1; + if(isWindows) + return "dll"; + else + return "so"; + } +} diff --git a/core/java/src/freenet/support/CPUInformation/CPUInfo.java b/core/java/src/freenet/support/CPUInformation/CPUInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..7d7691f534641dd3fb14cabd8ced87b7b0eb2bec --- /dev/null +++ b/core/java/src/freenet/support/CPUInformation/CPUInfo.java @@ -0,0 +1,45 @@ +/* + * Created on Jul 16, 2004 + * + */ +package freenet.support.CPUInformation; + +/** + * @author Iakin + * An interface for classes that provide lowlevel information about CPU's + * + * free (adj.): unencumbered; not under the control of others + * Written by Iakin in 2004 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + */ + +public interface CPUInfo +{ + /** + * @return A string indicating the vendor of the CPU. + */ + public String getVendor(); + /** + * @return A string detailing what type of CPU that is present in the machine. I.e. 'Pentium IV' etc. + * @throws UnknownCPUException If for any reson the retrieval of the requested information + * failed. The message encapsulated in the execption indicates the + * cause of the failure. + */ + public String getCPUModelString() throws UnknownCPUException; + + /** + * @return true iff the CPU support the MMX instruction set. + */ + public boolean hasMMX(); + /** + * @return true iff the CPU support the SSE instruction set. + */ + public boolean hasSSE(); + /** + * @return true iff the CPU support the SSE2 instruction set. + */ + public boolean hasSSE2(); + +} diff --git a/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java b/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..20f8aaf77e689e9c267218c30f4a17bccbcb2a4d --- /dev/null +++ b/core/java/src/freenet/support/CPUInformation/IntelCPUInfo.java @@ -0,0 +1,40 @@ +/* + * Created on Jul 17, 2004 + * + */ +package freenet.support.CPUInformation; + +/** + * @author Iakin + * An interface for classes that provide lowlevel information about Intel CPU's + * + * free (adj.): unencumbered; not under the control of others + * Written by Iakin in 2004 and released into the public domain + * with no warranty of any kind, either expressed or implied. + * It probably won't make your computer catch on fire, or eat + * your children, but it might. Use at your own risk. + */ +public interface IntelCPUInfo extends CPUInfo { + /** + * @return true iff the CPU is at least a Pentium CPU. + */ + public boolean IsPentiumCompatible(); + /** + * @return true iff the CPU is at least a Pentium which implements the MMX instruction/feature set. + */ + public boolean IsPentiumMMXCompatible(); + /** + * @return true iff the CPU implements at least the p6 instruction set (Pentium II or better). + * Please note that an PentimPro CPU causes/should cause this method to return false (due to that CPU using a + * very early implementation of the p6 instruction set. No MMX etc.) + */ + public boolean IsPentium2Compatible(); + /** + * @return true iff the CPU implements at least a Pentium III level of the p6 instruction/feature set. + */ + public boolean IsPentium3Compatible(); + /** + * @return true iff the CPU implements at least a Pentium IV level instruction/feature set. + */ + public boolean IsPentium4Compatible(); +} diff --git a/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java b/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java new file mode 100644 index 0000000000000000000000000000000000000000..f493980b258404a8f6dc03282a216f19dc6d1bc9 --- /dev/null +++ b/core/java/src/freenet/support/CPUInformation/UnknownCPUException.java @@ -0,0 +1,18 @@ +/* + * Created on Jul 16, 2004 + */ +package freenet.support.CPUInformation; + +/** + * @author Iakin + * + */ +public class UnknownCPUException extends RuntimeException { + public UnknownCPUException() { + super(); + } + + public UnknownCPUException(String message) { + super(message); + } +}