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

org.ehcache.impl.internal.concurrent.JSR166Helper Maven / Gradle / Ivy

There is a newer version: 3.10.8
Show newest version
/*
 * Copyright Terracotta, Inc.
 *
 * 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 org.ehcache.impl.internal.concurrent;

import java.lang.reflect.Field;

/**
 * @author Ludovic Orban
 */
public final class JSR166Helper {

    private JSR166Helper() {
    }

    public interface BiConsumer { void accept(A a, B b); }
    public interface Consumer { void accept(A a); }
    public interface ToLongFunction { long applyAsLong(A a); }
    public interface ToLongBiFunction { long applyAsLong(A a, B b); }
    public interface ToIntFunction {int applyAsInt(A a); }
    public interface ToIntBiFunction {int applyAsInt(A a, B b); }
    public interface ToDoubleFunction { double applyAsDouble(A a); }
    public interface ToDoubleBiFunction { double applyAsDouble(A a, B b); }
    public interface LongBinaryOperator { long applyAsLong(long a, long b); }
    public interface DoubleBinaryOperator { long applyAsDouble(double a, double b); }
    public interface IntBinaryOperator { int applyAsInt(int a, int b); }

    public static interface Spliterator {
        static final int DISTINCT   = 0x00000001;
        static final int NONNULL    = 0x00000100;
        static final int CONCURRENT = 0x00001000;

        static final int SIZED      = 0x00000040;
        static final int IMMUTABLE  = 0x00000400;
        static final int SUBSIZED   = 0x00004000;

        Spliterator trySplit();
        long estimateSize();
        void forEachRemaining(Consumer action);
        boolean tryAdvance(Consumer action);
        int characteristics();

        interface OfInt { }
        interface OfLong { }
        interface OfDouble { }
    }

    // only used by StreamSupport and ThreadLocalRandom
    interface IntStream {}
    interface IntConsumer { void accept(int i); }
    interface LongStream {}
    interface LongConsumer { void accept(long l); }
    interface DoubleStream {}
    interface DoubleConsumer { void accept(double v); }

    // only used by ThreadLocalRandom
    static class StreamSupport {
        static IntStream intStream(Spliterator.OfInt soi, boolean b) { throw new UnsupportedOperationException(); }
        static LongStream longStream(Spliterator.OfLong sol, boolean b) { throw new UnsupportedOperationException(); }
        static DoubleStream doubleStream(Spliterator.OfDouble sod, boolean b) { throw new UnsupportedOperationException(); }
    }

    // sun.misc.Unsafe wrapper that implements JDK8 intrinsics not available on JDK6
    static final class Unsafe {
        private static final sun.misc.Unsafe SMU;
        private static final Unsafe U;

        private static sun.misc.Unsafe getSMU() {
            try {
                return sun.misc.Unsafe.getUnsafe();
            } catch (SecurityException tryReflectionInstead) {
                // ignore
            }
            try {
                return java.security.AccessController.doPrivileged
                    (new java.security.PrivilegedExceptionAction() {
                        public sun.misc.Unsafe run() throws Exception {
                            Class k = sun.misc.Unsafe.class;
                            for (java.lang.reflect.Field f : k.getDeclaredFields()) {
                                f.setAccessible(true);
                                Object x = f.get(null);
                                if (k.isInstance(x))
                                    return k.cast(x);
                            }
                            throw new NoSuchFieldError("the Unsafe");
                        }
                    });
            } catch (java.security.PrivilegedActionException e) {
                throw new RuntimeException("Could not initialize intrinsics", e.getCause());
            }
        }

        static {
            try {
                SMU = getSMU();
                U = new Unsafe();
            } catch (Exception e) {
                throw new Error(e);
            }
        }

        private Unsafe() {
        }

        public static Unsafe getUnsafe() {
            return U;
        }

        public long    objectFieldOffset(Field pending) { return SMU.objectFieldOffset(pending); }
        public int     arrayBaseOffset(Class aClass) { return SMU.arrayBaseOffset(aClass); }
        public int     arrayIndexScale(Class aClass) { return SMU.arrayIndexScale(aClass); }
        public boolean compareAndSwapInt(Object o, long pending, int c, int i) { return SMU.compareAndSwapInt(o, pending, c, i); }
        public boolean compareAndSwapLong(Object o, long l, long l1, long l2) { return SMU.compareAndSwapLong(o, l, l1, l2); }
        public boolean compareAndSwapObject(Object o, long l, Object o1, Object o2) { return SMU.compareAndSwapObject(o, l, o1, o2); }
        public void    park(boolean b, long l) { SMU.park(b, l); }
        public void    unpark(Object o) { SMU.unpark(o); }
        public void    putInt(Object o, long l, int i) { SMU.putInt(o, l, i); }
        public void    putOrderedInt(Object o, long qtop, int i) { SMU.putOrderedInt(o, qtop, i); }
        public void    putObject(Object o, long l, Object o1) { SMU.putObject(o, l, o1); }
        public void    putOrderedObject(Object o, long l, Object o1) { SMU.putOrderedObject(o, l, o1); }
        public Object  getObject(Object o, long l) { return SMU.getObject(o, l); }
        public Object  getObjectVolatile(Object o, long l) { return SMU.getObjectVolatile(o, l); }
        public void    putObjectVolatile(Object o, long l, Object o1) { SMU.putObjectVolatile(o, l, o1); }

        public int getAndAddInt(Object o, long offset, int val) {
            while (true) {
                int temp = SMU.getIntVolatile(o, offset);
                if (SMU.compareAndSwapInt(o, offset, temp, temp + val)) { return temp; }
            }
        }
        public long getAndAddLong(Object o, long offset, long val) {
            while (true) {
                long temp = SMU.getLongVolatile(o, offset);
                if (SMU.compareAndSwapLong(o, offset, temp, temp + val)) { return temp; }
            }
        }
        public Object getAndSetObject(Object o, long offset, Object val) {
            while (true) {
                Object temp = SMU.getObjectVolatile(o, offset);
                if (SMU.compareAndSwapObject(o, offset, temp, val)) { return temp; }
            }
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy