I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit f7f05cfc authored by jrandom's avatar jrandom Committed by zzz
Browse files

imported Iakin's public domain jcpuid library allowing the detection of CPU types from java

imported Iakin's modifications to jbigi to use the jcpuid library in detecting what jbigi implementation to load
imported and slightly updated Iakin's scripts to build jbigi for lots of architectures
(yay iakin!)
parent f4754d74
No related branches found
No related tags found
No related merge requests found
Showing
with 1362 additions and 35 deletions
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/)
#!/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"
***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
#/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
#/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 ..
#!/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
/* 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
#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, &copy);
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 */
#/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
/* 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
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
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
File added
<?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="&quot;$(SolutionDir)\..\include&quot;"
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>
#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);
}
/*
* 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();
}
/*
* 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";
}
}
/*
* 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();
}
/*
* 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();
}
/*
* 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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment