< prev index next >

src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/SharedScope.java

Print this page
*** 23,18 ***
   * questions.
   */
  
  package jdk.internal.foreign;
  
- import jdk.incubator.foreign.ResourceScope;
  import jdk.internal.misc.ScopedMemoryAccess;
  
  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.VarHandle;
  import java.lang.ref.Cleaner;
- import java.lang.ref.Reference;
- import java.util.concurrent.atomic.AtomicBoolean;
  
  /**
   * A shared scope, which can be shared across multiple threads. Closing a shared scope has to ensure that
   * (i) only one thread can successfully close a scope (e.g. in a close vs. close race) and that
   * (ii) no other thread is accessing the memory associated with this scope while the segment is being
--- 23,16 ---
   * questions.
   */
  
  package jdk.internal.foreign;
  
  import jdk.internal.misc.ScopedMemoryAccess;
+ import jdk.internal.vm.annotation.ForceInline;
  
  import java.lang.invoke.MethodHandles;
  import java.lang.invoke.VarHandle;
  import java.lang.ref.Cleaner;
  
  /**
   * A shared scope, which can be shared across multiple threads. Closing a shared scope has to ensure that
   * (i) only one thread can successfully close a scope (e.g. in a close vs. close race) and that
   * (ii) no other thread is accessing the memory associated with this scope while the segment is being

*** 48,11 ***
      private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
  
      private static final int ALIVE = 0;
      private static final int CLOSING = -1;
      private static final int CLOSED = -2;
-     private static final int MAX_FORKS = Integer.MAX_VALUE;
  
      private int state = ALIVE;
  
      private static final VarHandle STATE;
  
--- 46,10 ---

*** 63,11 ***
              throw new ExceptionInInitializerError(ex);
          }
      }
  
      SharedScope(Cleaner cleaner) {
!         super(cleaner, new SharedResourceList());
      }
  
      @Override
      public Thread ownerThread() {
          return null;
--- 60,11 ---
              throw new ExceptionInInitializerError(ex);
          }
      }
  
      SharedScope(Cleaner cleaner) {
!         super(new SharedResourceList(), cleaner);
      }
  
      @Override
      public Thread ownerThread() {
          return null;

*** 79,31 ***
              throw ScopedAccessError.INSTANCE;
          }
      }
  
      @Override
!     public HandleImpl acquire() {
          int value;
          do {
              value = (int) STATE.getVolatile(this);
              if (value < ALIVE) {
                  //segment is not alive!
                  throw new IllegalStateException("Already closed");
              } else if (value == MAX_FORKS) {
                  //overflow
!                 throw new IllegalStateException("Segment acquire limit exceeded");
              }
          } while (!STATE.compareAndSet(this, value, value + 1));
!         return new SharedHandle();
      }
  
      void justClose() {
          int prevState = (int) STATE.compareAndExchange(this, ALIVE, CLOSING);
          if (prevState < 0) {
              throw new IllegalStateException("Already closed");
          } else if (prevState != ALIVE) {
!             throw new IllegalStateException("Scope is acquired by " + prevState + " locks");
          }
          boolean success = SCOPED_MEMORY_ACCESS.closeScope(this);
          STATE.setVolatile(this, success ? CLOSED : ALIVE);
          if (!success) {
              throw new IllegalStateException("Cannot close while another thread is accessing the segment");
--- 76,44 ---
              throw ScopedAccessError.INSTANCE;
          }
      }
  
      @Override
!     @ForceInline
+     public void acquire0() {
          int value;
          do {
              value = (int) STATE.getVolatile(this);
              if (value < ALIVE) {
                  //segment is not alive!
                  throw new IllegalStateException("Already closed");
              } else if (value == MAX_FORKS) {
                  //overflow
!                 throw new IllegalStateException("Scope keep alive limit exceeded");
              }
          } while (!STATE.compareAndSet(this, value, value + 1));
!     }
+ 
+     @Override
+     @ForceInline
+     public void release0() {
+         int value;
+         do {
+             value = (int) STATE.getVolatile(jdk.internal.foreign.SharedScope.this);
+             if (value <= ALIVE) {
+                 //cannot get here - we can't close segment twice
+                 throw new IllegalStateException("Already closed");
+             }
+         } while (!STATE.compareAndSet(jdk.internal.foreign.SharedScope.this, value, value - 1));
      }
  
      void justClose() {
          int prevState = (int) STATE.compareAndExchange(this, ALIVE, CLOSING);
          if (prevState < 0) {
              throw new IllegalStateException("Already closed");
          } else if (prevState != ALIVE) {
!             throw new IllegalStateException("Scope is kept alive by " + prevState + " scopes");
          }
          boolean success = SCOPED_MEMORY_ACCESS.closeScope(this);
          STATE.setVolatile(this, success ? CLOSED : ALIVE);
          if (!success) {
              throw new IllegalStateException("Cannot close while another thread is accessing the segment");

*** 165,32 ***
              } else {
                  throw new IllegalStateException("Attempt to cleanup an already closed resource list");
              }
          }
      }
- 
-     /**
-      * A shared resource scope handle; this implementation has to handle close vs. close races.
-      */
-     class SharedHandle implements HandleImpl {
-         final AtomicBoolean released = new AtomicBoolean(false);
- 
-         @Override
-         public ResourceScopeImpl scope() {
-             return SharedScope.this;
-         }
- 
-         @Override
-         public void release() {
-             if (released.compareAndSet(false, true)) {
-                 int value;
-                 do {
-                     value = (int) STATE.getVolatile(jdk.internal.foreign.SharedScope.this);
-                     if (value <= ALIVE) {
-                         //cannot get here - we can't close segment twice
-                         throw new IllegalStateException("Already closed");
-                     }
-                 } while (!STATE.compareAndSet(jdk.internal.foreign.SharedScope.this, value, value - 1));
-             }
-         }
-     }
  }
--- 175,6 ---
< prev index next >