package com.ximple.eofms.util;
|
|
//~--- JDK imports ------------------------------------------------------------
|
|
import java.nio.ByteOrder;
|
import java.security.AccessController;
|
import java.security.PrivilegedAction;
|
|
import sun.misc.VM;
|
|
/**
|
* Bits
|
* User: Ulysses
|
* Date: 2007/6/17
|
* Time: 上午 01:16:39
|
*/
|
public class Bits
|
{
|
// -- Unsafe access --
|
// private static final Unsafe unsafe = Unsafe.getUnsafe();
|
|
// -- Processor and memory-system properties --
|
private static ByteOrder byteOrder = null;
|
private static int pageSize = -1;
|
private static boolean unaligned;
|
private static boolean unalignedKnown = false;
|
|
// -- Direct memory management --
|
// A user-settable upper limit on the maximum amount of allocatable
|
// direct buffer memory. This value may be changed during VM
|
// initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
|
private static volatile long maxMemory = VM.maxDirectMemory();
|
private static volatile long reservedMemory = 0;
|
private static boolean memoryLimitSet = false;
|
|
private Bits()
|
{
|
}
|
|
// -- Swapping --
|
public static short swap(short x)
|
{
|
return (short) ((x << 8) | ((x >> 8) & 0xff));
|
}
|
|
public static char swap(char x)
|
{
|
return (char) ((x << 8) | ((x >> 8) & 0xff));
|
}
|
|
public static int swap(int x)
|
{
|
return (int) ((swap((short) x) << 16) | (swap((short) (x >> 16)) & 0xffff));
|
}
|
|
public static long swap(long x)
|
{
|
return (long) (((long) swap((int) (x)) << 32) | ((long) swap((int) (x >> 32)) & 0xffffffffL));
|
}
|
|
// -- get/put char --
|
static private char makeChar(byte b1, byte b0)
|
{
|
return (char) ((b1 << 8) | (b0 & 0xff));
|
}
|
|
private static byte char1(char x)
|
{
|
return (byte) (x >> 8);
|
}
|
|
private static byte char0(char x)
|
{
|
return (byte) (x >> 0);
|
}
|
|
// --get/put short--
|
public static short makeShort(byte b1, byte b0)
|
{
|
return (short) ((b1 << 8) | (b0 & 0xff));
|
}
|
|
private static byte short1(short x)
|
{
|
return (byte) (x >> 8);
|
}
|
|
public static byte short0(short x)
|
{
|
return (byte) (x >> 0);
|
}
|
|
// -- get/put int --
|
public static int makeInt(byte b3, byte b2, byte b1, byte b0)
|
{
|
return (int) ((((b3 & 0xff) << 24) | ((b2 & 0xff) << 16) | ((b1 & 0xff) << 8) | ((b0 & 0xff) << 0)));
|
}
|
|
public static int makeInt(short hiword, short loword)
|
{
|
return ((hiword & 0xffff) << 16) + (loword & 0xffff);
|
}
|
|
public static short getHiShort(int qwValue)
|
{
|
return ((short) (qwValue >>> 16));
|
}
|
|
public static short getLoShort(int qwValue)
|
{
|
return ((short) (qwValue & 0xFFFF));
|
}
|
|
public static byte int3(int x)
|
{
|
return (byte) (x >> 24);
|
}
|
|
public static byte int2(int x)
|
{
|
return (byte) (x >> 16);
|
}
|
|
private static byte int1(int x)
|
{
|
return (byte) (x >> 8);
|
}
|
|
private static byte int0(int x)
|
{
|
return (byte) (x >> 0);
|
}
|
|
// -- get/put long --
|
public static long makeLong(byte b7, byte b6, byte b5, byte b4, byte b3, byte b2, byte b1, byte b0)
|
{
|
return ((((long) b7 & 0xff) << 56) | (((long) b6 & 0xff) << 48) | (((long) b5 & 0xff) << 40) | (((long) b4 & 0xff) << 32)
|
| (((long) b3 & 0xff) << 24) | (((long) b2 & 0xff) << 16) | (((long) b1 & 0xff) << 8)
|
| (((long) b0 & 0xff) << 0));
|
}
|
|
public static long makeLong(int LoValue, int HiValue)
|
{
|
return (((long) HiValue & 0xFFFFFFFF) << 32) + (((long) LoValue) & 0xFFFFFFFF);
|
}
|
|
public static int getHiInt(long qwValue)
|
{
|
return ((int) (qwValue >>> 32));
|
}
|
|
public static int getLoInt(long qwValue)
|
{
|
return ((int) (qwValue & 0xFFFFFFFF));
|
}
|
|
private static byte long7(long x)
|
{
|
return (byte) (x >> 56);
|
}
|
|
private static byte long6(long x)
|
{
|
return (byte) (x >> 48);
|
}
|
|
private static byte long5(long x)
|
{
|
return (byte) (x >> 40);
|
}
|
|
private static byte long4(long x)
|
{
|
return (byte) (x >> 32);
|
}
|
|
private static byte long3(long x)
|
{
|
return (byte) (x >> 24);
|
}
|
|
private static byte long2(long x)
|
{
|
return (byte) (x >> 16);
|
}
|
|
private static byte long1(long x)
|
{
|
return (byte) (x >> 8);
|
}
|
|
private static byte long0(long x)
|
{
|
return (byte) (x >> 0);
|
}
|
|
// -- get/put float --
|
|
// -- get/put double --
|
|
/*
|
private static byte _get(long a)
|
{
|
return unsafe.getByte(a);
|
}
|
|
private static void _put(long a, byte b)
|
{
|
unsafe.putByte(a, b);
|
}
|
|
static Unsafe unsafe()
|
{
|
return unsafe;
|
}
|
|
static ByteOrder byteOrder()
|
{
|
if (byteOrder != null)
|
{
|
return byteOrder;
|
}
|
|
long a = unsafe.allocateMemory(8);
|
|
try
|
{
|
unsafe.putLong(a, 0x0102030405060708L);
|
|
byte b = unsafe.getByte(a);
|
|
switch (b)
|
{
|
case 0x01 :
|
byteOrder = ByteOrder.BIG_ENDIAN;
|
|
break;
|
|
case 0x08 :
|
byteOrder = ByteOrder.LITTLE_ENDIAN;
|
|
break;
|
|
default :
|
throw new Error("Unknown byte order");
|
}
|
} finally
|
{
|
unsafe.freeMemory(a);
|
}
|
|
return byteOrder;
|
}
|
*/
|
|
static boolean unaligned()
|
{
|
if (unalignedKnown)
|
{
|
return unaligned;
|
}
|
|
PrivilegedAction pa = new sun.security.action.GetPropertyAction("os.arch");
|
String arch = (String) AccessController.doPrivileged(pa);
|
|
unaligned = arch.equals("i386") || arch.equals("x86");
|
unalignedKnown = true;
|
|
return unaligned;
|
}
|
|
// These methods should be called whenever direct memory is allocated or
|
// freed. They allow the user to control the amount of direct memory
|
// which a process may access. All sizes are specified in bytes.
|
static void reserveMemory(long size)
|
{
|
synchronized (Bits.class)
|
{
|
if (!memoryLimitSet && VM.isBooted())
|
{
|
maxMemory = VM.maxDirectMemory();
|
memoryLimitSet = true;
|
}
|
|
if (size <= maxMemory - reservedMemory)
|
{
|
reservedMemory += size;
|
|
return;
|
}
|
}
|
|
System.gc();
|
|
try
|
{
|
Thread.sleep(100);
|
} catch (InterruptedException x)
|
{
|
// Restore interrupt status
|
Thread.currentThread().interrupt();
|
}
|
|
synchronized (Bits.class)
|
{
|
if (reservedMemory + size > maxMemory)
|
{
|
throw new OutOfMemoryError("Direct buffer memory");
|
}
|
|
reservedMemory += size;
|
}
|
}
|
|
static synchronized void unreserveMemory(long size)
|
{
|
if (reservedMemory > 0)
|
{
|
reservedMemory -= size;
|
assert (reservedMemory > -1);
|
}
|
}
|
}
|