All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.voltcore.utils.Bits Maven / Gradle / Ivy

There is a newer version: 10.1.1
Show newest version
/* This file is part of VoltDB.
 * Copyright (C) 2008-2018 VoltDB Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see .
 */

package org.voltcore.utils;

import java.io.FileDescriptor;
import java.io.IOException;
import java.nio.channels.FileChannel;

import org.voltcore.logging.VoltLogger;
import org.voltcore.utils.DBBPool.BBContainer;
import org.voltdb.utils.PosixAdvise;

/**
 * Utility class for accessing a variety of com.sun.misc.Unsafe stuff
 */
public final class Bits {

    public static final sun.misc.Unsafe unsafe;

    private static sun.misc.Unsafe getUnsafe() {
        try {
            return sun.misc.Unsafe.getUnsafe();
        } catch (SecurityException se) {
            try {
                return java.security.AccessController.doPrivileged
                        (new java.security
                                .PrivilegedExceptionAction() {
                            @Override
                            public sun.misc.Unsafe run() throws Exception {
                                java.lang.reflect.Field f = sun.misc
                                        .Unsafe.class.getDeclaredField("theUnsafe");
                                f.setAccessible(true);
                                return (sun.misc.Unsafe) f.get(null);
                            }});
            } catch (java.security.PrivilegedActionException e) {
                throw new RuntimeException("Could not initialize intrinsics",
                        e.getCause());
            }
        }
    }

    private static int PAGE_SIZE = -1;

    static {
        sun.misc.Unsafe unsafeTemp = null;
        try {
            unsafeTemp = getUnsafe();
        } catch (Exception e) {
            e.printStackTrace();
        }
        unsafe = unsafeTemp;
    }

    public static int pageSize() {
        if (PAGE_SIZE == -1) {
            PAGE_SIZE = unsafe.pageSize();
        }
        return PAGE_SIZE;
    }

    public static int numPages(int size) {
        return (size + pageSize()  - 1) / pageSize();
    }

    //Target for storing the checksum to prevent dead code elimination
    private static byte unused;

    public static void readEveryPage(BBContainer cont) {
        long address = cont.address();
        //Make address page aligned
        final int offset = (int)(address % Bits.pageSize());
        address -= offset;
        final int numPages = Bits.numPages(cont.b().remaining() + offset);
        byte checksum = 0;
        for (int ii = 0; ii < numPages; ii++) {
            checksum ^= Bits.unsafe.getByte(address);
            address += PAGE_SIZE;
        }
        //This store will never actually occur, but the compiler doesn't care
        //for the purposes of dead code elimination
        if (unused != 0) {
            unused = checksum;
        }
    }

    public static long sync_file_range(VoltLogger logger, FileDescriptor fd, FileChannel fc, long syncStart, long positionAtSync) throws IOException {
        //Don't start writeback on the currently appending page to avoid
        //issues with stables pages, hence we move the end back one page
        long syncedBytes = ((positionAtSync / Bits.pageSize()) - 1) * Bits.pageSize();
        if (PosixAdvise.SYNC_FILE_RANGE_SUPPORTED) {
            final long retval = PosixAdvise.sync_file_range(fd,
                                                            syncStart,
                                                            syncedBytes - syncStart,
                                                            PosixAdvise.SYNC_FILE_RANGE_SYNC);
            if (retval != 0) {
                logger.error("Error sync_file_range snapshot data: " + retval);
                logger.error(
                        "Params offset " + syncedBytes +
                        " length " + (syncedBytes - syncStart) +
                        " flags " + PosixAdvise.SYNC_FILE_RANGE_SYNC);
                fc.force(false);
            }
        } else {
            fc.force(false);
        }
        return syncedBytes;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy