< prev index next >

src/java.base/share/classes/jdk/internal/vm/Continuation.java

Print this page

 39 
 40 /**
 41  * A one-shot delimited continuation.
 42  */
 43 public class Continuation {
 44     private static final Unsafe U = Unsafe.getUnsafe();
 45     private static final long MOUNTED_OFFSET = U.objectFieldOffset(Continuation.class, "mounted");
 46     private static final boolean PRESERVE_SCOPED_VALUE_CACHE;
 47     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 48     static {
 49         ContinuationSupport.ensureSupported();
 50 
 51         StackChunk.init(); // ensure StackChunk class is initialized
 52 
 53         String value = GetPropertyAction.privilegedGetProperty("jdk.preserveScopedValueCache");
 54         PRESERVE_SCOPED_VALUE_CACHE = (value == null) || Boolean.parseBoolean(value);
 55     }
 56 
 57     /** Reason for pinning */
 58     public enum Pinned {
 59         /** Native frame on stack */ NATIVE,
 60         /** Monitor held */          MONITOR,
 61         /** In critical section */   CRITICAL_SECTION }









 62 
 63     /** Preemption attempt result */
 64     public enum PreemptStatus {
 65         /** Success */                                                      SUCCESS(null),
 66         /** Permanent failure */                                            PERM_FAIL_UNSUPPORTED(null),
 67         /** Permanent failure: continuation already yielding */             PERM_FAIL_YIELDING(null),
 68         /** Permanent failure: continuation not mounted on the thread */    PERM_FAIL_NOT_MOUNTED(null),
 69         /** Transient failure: continuation pinned due to a held CS */      TRANSIENT_FAIL_PINNED_CRITICAL_SECTION(Pinned.CRITICAL_SECTION),
 70         /** Transient failure: continuation pinned due to native frame */   TRANSIENT_FAIL_PINNED_NATIVE(Pinned.NATIVE),
 71         /** Transient failure: continuation pinned due to a held monitor */ TRANSIENT_FAIL_PINNED_MONITOR(Pinned.MONITOR);
 72 
 73         final Pinned pinned;
 74         private PreemptStatus(Pinned reason) { this.pinned = reason; }
 75         /**
 76          * Whether or not the continuation is pinned.
 77          * @return whether or not the continuation is pinned
 78          **/
 79         public Pinned pinned() { return pinned; }
 80     }
 81 

336      * Suspends the current continuations up to the given scope
337      *
338      * @param scope The {@link ContinuationScope} to suspend
339      * @return {@code true} for success; {@code false} for failure
340      * @throws IllegalStateException if not currently in the given {@code scope},
341      */
342     @Hidden
343     public static boolean yield(ContinuationScope scope) {
344         Continuation cont = JLA.getContinuation(currentCarrierThread());
345         Continuation c;
346         for (c = cont; c != null && c.scope != scope; c = c.parent)
347             ;
348         if (c == null)
349             throw new IllegalStateException("Not in scope " + scope);
350 
351         return cont.yield0(scope, null);
352     }
353 
354     @Hidden
355     private boolean yield0(ContinuationScope scope, Continuation child) {
356         preempted = false;
357 
358         if (scope != this.scope)
359             this.yieldInfo = scope;
360         int res = doYield();
361         U.storeFence(); // needed to prevent certain transformations by the compiler
362 
363         assert scope != this.scope || yieldInfo == null : "scope: " + scope + " this.scope: " + this.scope + " yieldInfo: " + yieldInfo + " res: " + res;
364         assert yieldInfo == null || scope == this.scope || yieldInfo instanceof Integer : "scope: " + scope + " this.scope: " + this.scope + " yieldInfo: " + yieldInfo + " res: " + res;
365 
366         if (child != null) { // TODO: ugly
367             if (res != 0) {
368                 child.yieldInfo = res;
369             } else if (yieldInfo != null) {
370                 assert yieldInfo instanceof Integer;
371                 child.yieldInfo = yieldInfo;
372             } else {
373                 child.yieldInfo = res;
374             }
375             this.yieldInfo = null;
376         } else {
377             if (res == 0 && yieldInfo != null) {

 39 
 40 /**
 41  * A one-shot delimited continuation.
 42  */
 43 public class Continuation {
 44     private static final Unsafe U = Unsafe.getUnsafe();
 45     private static final long MOUNTED_OFFSET = U.objectFieldOffset(Continuation.class, "mounted");
 46     private static final boolean PRESERVE_SCOPED_VALUE_CACHE;
 47     private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 48     static {
 49         ContinuationSupport.ensureSupported();
 50 
 51         StackChunk.init(); // ensure StackChunk class is initialized
 52 
 53         String value = GetPropertyAction.privilegedGetProperty("jdk.preserveScopedValueCache");
 54         PRESERVE_SCOPED_VALUE_CACHE = (value == null) || Boolean.parseBoolean(value);
 55     }
 56 
 57     /** Reason for pinning */
 58     public enum Pinned {
 59         /** Native frame on stack */ NATIVE(2),
 60         /** Monitor held */          MONITOR(3),
 61         /** In critical section */   CRITICAL_SECTION(4);
 62 
 63         private final int value;
 64         Pinned(int value) {
 65             this.value = value;
 66         }
 67         public int value() {
 68             return value;
 69         }
 70     }
 71 
 72     /** Preemption attempt result */
 73     public enum PreemptStatus {
 74         /** Success */                                                      SUCCESS(null),
 75         /** Permanent failure */                                            PERM_FAIL_UNSUPPORTED(null),
 76         /** Permanent failure: continuation already yielding */             PERM_FAIL_YIELDING(null),
 77         /** Permanent failure: continuation not mounted on the thread */    PERM_FAIL_NOT_MOUNTED(null),
 78         /** Transient failure: continuation pinned due to a held CS */      TRANSIENT_FAIL_PINNED_CRITICAL_SECTION(Pinned.CRITICAL_SECTION),
 79         /** Transient failure: continuation pinned due to native frame */   TRANSIENT_FAIL_PINNED_NATIVE(Pinned.NATIVE),
 80         /** Transient failure: continuation pinned due to a held monitor */ TRANSIENT_FAIL_PINNED_MONITOR(Pinned.MONITOR);
 81 
 82         final Pinned pinned;
 83         private PreemptStatus(Pinned reason) { this.pinned = reason; }
 84         /**
 85          * Whether or not the continuation is pinned.
 86          * @return whether or not the continuation is pinned
 87          **/
 88         public Pinned pinned() { return pinned; }
 89     }
 90 

345      * Suspends the current continuations up to the given scope
346      *
347      * @param scope The {@link ContinuationScope} to suspend
348      * @return {@code true} for success; {@code false} for failure
349      * @throws IllegalStateException if not currently in the given {@code scope},
350      */
351     @Hidden
352     public static boolean yield(ContinuationScope scope) {
353         Continuation cont = JLA.getContinuation(currentCarrierThread());
354         Continuation c;
355         for (c = cont; c != null && c.scope != scope; c = c.parent)
356             ;
357         if (c == null)
358             throw new IllegalStateException("Not in scope " + scope);
359 
360         return cont.yield0(scope, null);
361     }
362 
363     @Hidden
364     private boolean yield0(ContinuationScope scope, Continuation child) {


365         if (scope != this.scope)
366             this.yieldInfo = scope;
367         int res = doYield();
368         U.storeFence(); // needed to prevent certain transformations by the compiler
369 
370         assert scope != this.scope || yieldInfo == null : "scope: " + scope + " this.scope: " + this.scope + " yieldInfo: " + yieldInfo + " res: " + res;
371         assert yieldInfo == null || scope == this.scope || yieldInfo instanceof Integer : "scope: " + scope + " this.scope: " + this.scope + " yieldInfo: " + yieldInfo + " res: " + res;
372 
373         if (child != null) { // TODO: ugly
374             if (res != 0) {
375                 child.yieldInfo = res;
376             } else if (yieldInfo != null) {
377                 assert yieldInfo instanceof Integer;
378                 child.yieldInfo = yieldInfo;
379             } else {
380                 child.yieldInfo = res;
381             }
382             this.yieldInfo = null;
383         } else {
384             if (res == 0 && yieldInfo != null) {
< prev index next >