
io.questdb.std.Unsafe Maven / Gradle / Ivy
/*******************************************************************************
* ___ _ ____ ____
* / _ \ _ _ ___ ___| |_| _ \| __ )
* | | | | | | |/ _ \/ __| __| | | | _ \
* | |_| | |_| | __/\__ \ |_| |_| | |_) |
* \__\_\\__,_|\___||___/\__|____/|____/
*
* Copyright (c) 2014-2019 Appsicle
* Copyright (c) 2019-2020 QuestDB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
package io.questdb.std;
import io.questdb.std.ex.FatalError;
import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicLong;
public final class Unsafe {
public static final long INT_OFFSET;
public static final long INT_SCALE;
public static final long LONG_OFFSET;
public static final long LONG_SCALE;
static final AtomicLong MEM_USED = new AtomicLong(0);
private static final sun.misc.Unsafe UNSAFE;
private static final AtomicLong MALLOC_COUNT = new AtomicLong(0);
private static final AtomicLong FREE_COUNT = new AtomicLong(0);
static {
try {
Field theUnsafe = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (sun.misc.Unsafe) theUnsafe.get(null);
INT_OFFSET = Unsafe.getUnsafe().arrayBaseOffset(int[].class);
INT_SCALE = msb(Unsafe.getUnsafe().arrayIndexScale(int[].class));
LONG_OFFSET = Unsafe.getUnsafe().arrayBaseOffset(long[].class);
LONG_SCALE = msb(Unsafe.getUnsafe().arrayIndexScale(long[].class));
} catch (Exception e) {
throw new FatalError(e);
}
}
private Unsafe() {
}
public static long arrayGetVolatile(long[] array, int index) {
assert index > -1 && index < array.length;
return Unsafe.getUnsafe().getLongVolatile(array, LONG_OFFSET + (index << LONG_SCALE));
}
public static void arrayPutOrdered(long[] array, int index, long value) {
assert index > -1 && index < array.length;
Unsafe.getUnsafe().putOrderedLong(array, LONG_OFFSET + (index << LONG_SCALE), value);
}
public static long calloc(long size) {
long ptr = malloc(size);
getUnsafe().setMemory(ptr, size, (byte) 0);
return ptr;
}
public static boolean cas(Object o, long offset, long expected, long value) {
return UNSAFE.compareAndSwapLong(o, offset, expected, value);
}
public static boolean cas(Object o, long offset, int expected, int value) {
return UNSAFE.compareAndSwapInt(o, offset, expected, value);
}
public static boolean cas(long[] array, int index, long expected, long value) {
assert index > -1 && index < array.length;
return Unsafe.cas(array, Unsafe.LONG_OFFSET + (((long) index) << Unsafe.LONG_SCALE), expected, value);
}
public static void free(long ptr, long size) {
getUnsafe().freeMemory(ptr);
FREE_COUNT.incrementAndGet();
recordMemAlloc(-size);
}
public static boolean getBool(long address) {
return UNSAFE.getByte(address) == 1;
}
public static long getFieldOffset(Class clazz, String name) {
try {
Field f = clazz.getDeclaredField(name);
f.setAccessible(true);
return UNSAFE.objectFieldOffset(f);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
public static long getFreeCount() {
return FREE_COUNT.get();
}
public static long getMallocCount() {
return MALLOC_COUNT.get();
}
public static long getMemUsed() {
return MEM_USED.get();
}
public static sun.misc.Unsafe getUnsafe() {
return UNSAFE;
}
public static long malloc(long size) {
long ptr = getUnsafe().allocateMemory(size);
recordMemAlloc(size);
MALLOC_COUNT.incrementAndGet();
return ptr;
}
public static long realloc(long address, long oldSize, long newSize) {
long ptr = getUnsafe().reallocateMemory(address, newSize);
recordMemAlloc(-oldSize + newSize);
return ptr;
}
static void recordMemAlloc(long size) {
MEM_USED.addAndGet(size);
}
private static int msb(int value) {
return 31 - Integer.numberOfLeadingZeros(value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy