/*
 * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.oracle.svm.core.threadlocal;

import java.util.function.IntSupplier;

import org.graalvm.nativeimage.IsolateThread;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.word.PointerBase;
import org.graalvm.word.WordBase;

This class contains factory methods to create fast thread local variables. A thread local variable is represented as an object, with different classes for primitive int (class FastThreadLocalInt), primitive long (class FastThreadLocalLong), Object (class FastThreadLocalObject), and word (class FastThreadLocalWord) values. Access to such thread local variables is significantly faster than regular Java ThreadLocal variables. However, there are several restrictions:
  • The thread local object must be created during native image generation. Otherwise, the size of the IsolateThread data structure would not be a compile time constant.
  • It is not possible to access the value of a thread local variable during native image generation. Attempts to do so will result in an error during native image generation.
  • The initial value of a thread local variable is 0 or null for every newly created thread. There is no possibility to specify an initial value.
  • A thread local variable created by this factory must be assigned to one static final field. The name of that field is used as the name of the local variable. The name is used to sort the variables in the IsolateThread data structure, to make the layout deterministic and reproducible.
  • When accessing the value, the thread local variable must be a compile time constant. This is fulfilled when the value is accessed from the static final field, which is the intended use case.

The implementation of fast thread local variables and the way the data is stored is implementation specific and transparent for users of it. However, the access is fast and never requires object allocation.

/** * This class contains factory methods to create fast thread local variables. A thread local * variable is represented as an object, with different classes for primitive {@code int} (class * {@link FastThreadLocalInt}), primitive {@code long} (class {@link FastThreadLocalLong}), * {@link Object} (class {@link FastThreadLocalObject}), and {@link WordBase word} (class * {@link FastThreadLocalWord}) values. Access to such thread local variables is significantly * faster than regular Java {@link ThreadLocal} variables. However, there are several restrictions: * <ul> * <li>The thread local object must be created during native image generation. Otherwise, the size * of the {@link IsolateThread} data structure would not be a compile time constant. * <li>It is not possible to access the value of a thread local variable during native image * generation. Attempts to do so will result in an error during native image generation. * <li>The initial value of a thread local variable is 0 or {@code null} for every newly created * thread. There is no possibility to specify an initial value. * <li>A thread local variable created by this factory must be assigned to one {@code static final} * field. The name of that field is used as the name of the local variable. The name is used to sort * the variables in the {@link IsolateThread} data structure, to make the layout deterministic and * reproducible. * <li>When accessing the value, the thread local variable must be a compile time constant. This is * fulfilled when the value is accessed from the {@code static final} field, which is the intended * use case. * </ul> * <p> * The implementation of fast thread local variables and the way the data is stored is * implementation specific and transparent for users of it. However, the access is fast and never * requires object allocation. */
@Platforms(Platform.HOSTED_ONLY.class) public final class FastThreadLocalFactory { private FastThreadLocalFactory() { }
Creates a new fast thread local variable of the primitive type int.
/** * Creates a new fast thread local variable of the primitive type {@code int}. */
public static FastThreadLocalInt createInt() { return new FastThreadLocalInt(); }
Creates a new fast thread local variable of the primitive type long.
/** * Creates a new fast thread local variable of the primitive type {@code long}. */
public static FastThreadLocalLong createLong() { return new FastThreadLocalLong(); }
Creates a new fast thread local variable of type word.
/** * Creates a new fast thread local variable of type {@link WordBase word}. */
public static <T extends WordBase> FastThreadLocalWord<T> createWord() { return new FastThreadLocalWord<>(); }
Creates a new fast thread local variable of type Object.
/** * Creates a new fast thread local variable of type {@link Object}. */
public static <T> FastThreadLocalObject<T> createObject(Class<T> valueClass) { return new FastThreadLocalObject<>(valueClass); }
Creates a new fast thread local memory block that has a user-defined size.
/** * Creates a new fast thread local memory block that has a user-defined size. */
public static <T extends PointerBase> FastThreadLocalBytes<T> createBytes(IntSupplier sizeSupplier) { return new FastThreadLocalBytes<>(sizeSupplier); } }