Package org.lwjgl.util.mapped

Source Code of org.lwjgl.util.mapped.CacheUtil

/*
* Copyright (c) 2002-2011 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
*   its contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.util.mapped;

import org.lwjgl.LWJGLUtil;
import org.lwjgl.MemoryUtil;
import org.lwjgl.PointerBuffer;

import java.nio.*;

/**
* This class provides utility methods for allocating cache-line-aligned
* NIO buffers. The CPU cache line size is detected using a micro-benchmark
* that exploits the performation degredation that occurs when different
* threads write to different locations of the same cache line. The detection
* should be reasonably robust on both the server and client VM, but there
* are a few system properties that can be used to tune it.
*
* @author Spasi
*/
public final class CacheUtil {

  private static final int CACHE_LINE_SIZE;

  static {
    final Integer size = LWJGLUtil.getPrivilegedInteger("org.lwjgl.util.mapped.CacheLineSize"); // forces a specific cache line size

    if ( size != null ) {
      if ( size < 1 )
        throw new IllegalStateException("Invalid CacheLineSize specified: " + size);
      CACHE_LINE_SIZE = size;
    } else if ( Runtime.getRuntime().availableProcessors() == 1 ) { // We cannot use false sharing to detect it
      /*
          Spasi:

          I have implemented a single-threaded benchmark for this, but it requires
          lots of memory allocations and could not tune it for both the client and
          server VM. It's not a big deal anyway, 64 bytes should be ok for any
          single-core CPU.
      */
      if ( LWJGLUtil.DEBUG )
        LWJGLUtil.log("Cannot detect cache line size on single-core CPUs, assuming 64 bytes.");
      CACHE_LINE_SIZE = 64;
    } else
      CACHE_LINE_SIZE = CacheLineSize.getCacheLineSize();
  }

  private CacheUtil() {
  }

  /**
   * Returns the CPU cache line size, in number of bytes.
   *
   * @return the cache line size
   */
  public static int getCacheLineSize() {
    return CACHE_LINE_SIZE;
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned bytebuffer with the specified size.
   *
   * @param size The size, in bytes
   *
   * @return a ByteBuffer
   */
  public static ByteBuffer createByteBuffer(int size) {
    ByteBuffer buffer = ByteBuffer.allocateDirect(size + CACHE_LINE_SIZE);

    // Align to cache line.
    if ( MemoryUtil.getAddress(buffer) % CACHE_LINE_SIZE != 0 ) {
      // Round up to cache line boundary
      buffer.position(CACHE_LINE_SIZE - (int)(MemoryUtil.getAddress(buffer) & (CACHE_LINE_SIZE - 1)));
    }

    buffer.limit(buffer.position() + size);
    return buffer.slice().order(ByteOrder.nativeOrder());
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned shortbuffer with the specified number
   * of elements.
   *
   * @param size The size, in shorts
   *
   * @return a ShortBuffer
   */
  public static ShortBuffer createShortBuffer(int size) {
    return createByteBuffer(size << 1).asShortBuffer();
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned charbuffer with the specified number
   * of elements.
   *
   * @param size The size, in chars
   *
   * @return an CharBuffer
   */
  public static CharBuffer createCharBuffer(int size) {
    return createByteBuffer(size << 1).asCharBuffer();
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned intbuffer with the specified number
   * of elements.
   *
   * @param size The size, in ints
   *
   * @return an IntBuffer
   */
  public static IntBuffer createIntBuffer(int size) {
    return createByteBuffer(size << 2).asIntBuffer();
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned longbuffer with the specified number
   * of elements.
   *
   * @param size The size, in longs
   *
   * @return an LongBuffer
   */
  public static LongBuffer createLongBuffer(int size) {
    return createByteBuffer(size << 3).asLongBuffer();
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned floatbuffer with the specified number
   * of elements.
   *
   * @param size The size, in floats
   *
   * @return a FloatBuffer
   */
  public static FloatBuffer createFloatBuffer(int size) {
    return createByteBuffer(size << 2).asFloatBuffer();
  }

  /**
   * Construct a direct, native-ordered and cache-line-aligned doublebuffer with the specified number
   * of elements.
   *
   * @param size The size, in floats
   *
   * @return a FloatBuffer
   */
  public static DoubleBuffer createDoubleBuffer(int size) {
    return createByteBuffer(size << 3).asDoubleBuffer();
  }

  /**
   * Construct a cache-line-aligned PointerBuffer with the specified number
   * of elements.
   *
   * @param size The size, in memory addresses
   *
   * @return a PointerBuffer
   */
  public static PointerBuffer createPointerBuffer(int size) {
    return new PointerBuffer(createByteBuffer(size * PointerBuffer.getPointerSize()));
  }

}
TOP

Related Classes of org.lwjgl.util.mapped.CacheUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.