|
29 | 29 | import com.google.common.collect.Lists;
|
30 | 30 | import com.google.common.util.concurrent.AbstractFutureBenchmarks.OldAbstractFuture;
|
31 | 31 | import com.google.errorprone.annotations.concurrent.GuardedBy;
|
32 |
| -import java.lang.reflect.Field; |
33 |
| -import java.security.AccessController; |
34 |
| -import java.security.PrivilegedActionException; |
35 |
| -import java.security.PrivilegedExceptionAction; |
36 | 32 | import java.util.Queue;
|
37 | 33 | import java.util.concurrent.ArrayBlockingQueue;
|
38 | 34 | import java.util.concurrent.CountDownLatch;
|
|
44 | 40 | import java.util.logging.Logger;
|
45 | 41 | import org.jspecify.annotations.NullUnmarked;
|
46 | 42 | import org.jspecify.annotations.Nullable;
|
47 |
| -import sun.misc.Unsafe; |
48 | 43 |
|
49 | 44 | /** Benchmarks for {@link ExecutionList}. */
|
50 | 45 | @VmOptions({"-Xms8g", "-Xmx8g"})
|
@@ -85,29 +80,6 @@ public Object getImpl() {
|
85 | 80 | };
|
86 | 81 | }
|
87 | 82 | },
|
88 |
| - NEW_WITH_CAS { |
89 |
| - @Override |
90 |
| - ExecutionListWrapper newExecutionList() { |
91 |
| - return new ExecutionListWrapper() { |
92 |
| - final ExecutionListUsingCompareAndSwap list = new ExecutionListUsingCompareAndSwap(); |
93 |
| - |
94 |
| - @Override |
95 |
| - public void add(Runnable runnable, Executor executor) { |
96 |
| - list.add(runnable, executor); |
97 |
| - } |
98 |
| - |
99 |
| - @Override |
100 |
| - public void execute() { |
101 |
| - list.execute(); |
102 |
| - } |
103 |
| - |
104 |
| - @Override |
105 |
| - public Object getImpl() { |
106 |
| - return list; |
107 |
| - } |
108 |
| - }; |
109 |
| - } |
110 |
| - }, |
111 | 83 | NEW_WITH_QUEUE {
|
112 | 84 | @Override
|
113 | 85 | ExecutionListWrapper newExecutionList() {
|
@@ -578,127 +550,4 @@ private static final class RunnableExecutorPair {
|
578 | 550 | }
|
579 | 551 | }
|
580 | 552 | }
|
581 |
| - |
582 |
| - // A version of the list that uses compare and swap to manage the stack without locks. |
583 |
| - @SuppressWarnings({"SunApi", "removal"}) // b/345822163 |
584 |
| - private static final class ExecutionListUsingCompareAndSwap { |
585 |
| - static final Logger log = Logger.getLogger(ExecutionListUsingCompareAndSwap.class.getName()); |
586 |
| - |
587 |
| - private static final Unsafe UNSAFE; |
588 |
| - private static final long HEAD_OFFSET; |
589 |
| - |
590 |
| - /** |
591 |
| - * A special instance of {@link RunnableExecutorPair} that is used as a sentinel value for the |
592 |
| - * bottom of the stack. |
593 |
| - */ |
594 |
| - private static final RunnableExecutorPair NULL_PAIR = new RunnableExecutorPair(null, null); |
595 |
| - |
596 |
| - static { |
597 |
| - try { |
598 |
| - UNSAFE = getUnsafe(); |
599 |
| - HEAD_OFFSET = |
600 |
| - UNSAFE.objectFieldOffset( |
601 |
| - ExecutionListUsingCompareAndSwap.class.getDeclaredField("head")); |
602 |
| - } catch (Exception ex) { |
603 |
| - throw new Error(ex); |
604 |
| - } |
605 |
| - } |
606 |
| - |
607 |
| - /** TODO(lukes): This was copied verbatim from Striped64.java... standardize this? */ |
608 |
| - private static Unsafe getUnsafe() { |
609 |
| - try { |
610 |
| - return Unsafe.getUnsafe(); |
611 |
| - } catch (SecurityException tryReflectionInstead) { |
612 |
| - } |
613 |
| - try { |
614 |
| - return AccessController.doPrivileged( |
615 |
| - new PrivilegedExceptionAction<Unsafe>() { |
616 |
| - @Override |
617 |
| - public Unsafe run() throws Exception { |
618 |
| - Class<Unsafe> k = Unsafe.class; |
619 |
| - for (Field f : k.getDeclaredFields()) { |
620 |
| - f.setAccessible(true); |
621 |
| - Object x = f.get(null); |
622 |
| - if (k.isInstance(x)) return k.cast(x); |
623 |
| - } |
624 |
| - throw new NoSuchFieldError("the Unsafe"); |
625 |
| - } |
626 |
| - }); |
627 |
| - } catch (PrivilegedActionException e) { |
628 |
| - throw new RuntimeException("Could not initialize intrinsics", e.getCause()); |
629 |
| - } |
630 |
| - } |
631 |
| - |
632 |
| - private volatile RunnableExecutorPair head = NULL_PAIR; |
633 |
| - |
634 |
| - public void add(Runnable runnable, Executor executor) { |
635 |
| - Preconditions.checkNotNull(runnable, "Runnable was null."); |
636 |
| - Preconditions.checkNotNull(executor, "Executor was null."); |
637 |
| - |
638 |
| - RunnableExecutorPair newHead = new RunnableExecutorPair(runnable, executor); |
639 |
| - RunnableExecutorPair oldHead; |
640 |
| - do { |
641 |
| - oldHead = head; |
642 |
| - if (oldHead == null) { |
643 |
| - // If runnables == null then execute() has been called so we should just execute our |
644 |
| - // listener immediately. |
645 |
| - newHead.execute(); |
646 |
| - return; |
647 |
| - } |
648 |
| - // Try to make newHead the new head of the stack at runnables. |
649 |
| - newHead.next = oldHead; |
650 |
| - } while (!UNSAFE.compareAndSwapObject(this, HEAD_OFFSET, oldHead, newHead)); |
651 |
| - } |
652 |
| - |
653 |
| - public void execute() { |
654 |
| - RunnableExecutorPair stack; |
655 |
| - do { |
656 |
| - stack = head; |
657 |
| - if (stack == null) { |
658 |
| - // If head == null then execute() has been called so we should just return |
659 |
| - return; |
660 |
| - } |
661 |
| - // try to swap null into head. |
662 |
| - } while (!UNSAFE.compareAndSwapObject(this, HEAD_OFFSET, stack, null)); |
663 |
| - |
664 |
| - RunnableExecutorPair reversedStack = null; |
665 |
| - while (stack != NULL_PAIR) { |
666 |
| - RunnableExecutorPair head = stack; |
667 |
| - stack = stack.next; |
668 |
| - head.next = reversedStack; |
669 |
| - reversedStack = head; |
670 |
| - } |
671 |
| - stack = reversedStack; |
672 |
| - while (stack != null) { |
673 |
| - stack.execute(); |
674 |
| - stack = stack.next; |
675 |
| - } |
676 |
| - } |
677 |
| - |
678 |
| - private static class RunnableExecutorPair { |
679 |
| - final Runnable runnable; |
680 |
| - final Executor executor; |
681 |
| - // Volatile because this is written on one thread and read on another with no synchronization. |
682 |
| - @Nullable volatile RunnableExecutorPair next; |
683 |
| - |
684 |
| - RunnableExecutorPair(@Nullable Runnable runnable, @Nullable Executor executor) { |
685 |
| - this.runnable = runnable; |
686 |
| - this.executor = executor; |
687 |
| - } |
688 |
| - |
689 |
| - void execute() { |
690 |
| - try { |
691 |
| - executor.execute(runnable); |
692 |
| - } catch (RuntimeException e) { |
693 |
| - log.log( |
694 |
| - Level.SEVERE, |
695 |
| - "RuntimeException while executing runnable " |
696 |
| - + runnable |
697 |
| - + " with executor " |
698 |
| - + executor, |
699 |
| - e); |
700 |
| - } |
701 |
| - } |
702 |
| - } |
703 |
| - } |
704 | 553 | }
|
0 commit comments