< 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(2, "Native frame or <clinit> on stack"),
 60         MONITOR(3, "Monitor held"),
 61         CRITICAL_SECTION(4, "In critical section");
 62 
 63         private final int reasonCode;
 64         private final String reasonString;
 65         Pinned(int reasonCode, String reasonString) {
 66             this.reasonCode = reasonCode;
 67             this.reasonString = reasonString;
 68         }
 69         public int reasonCode() {
 70             return reasonCode;
 71         }
 72         public String reasonString() {
 73             return reasonString;
 74         }
 75     }
 76 
 77     /** Preemption attempt result */
 78     public enum PreemptStatus {
 79         /** Success */                                                      SUCCESS(null),
 80         /** Permanent failure */                                            PERM_FAIL_UNSUPPORTED(null),
 81         /** Permanent failure: continuation already yielding */             PERM_FAIL_YIELDING(null),
 82         /** Permanent failure: continuation not mounted on the thread */    PERM_FAIL_NOT_MOUNTED(null),
 83         /** Transient failure: continuation pinned due to a held CS */      TRANSIENT_FAIL_PINNED_CRITICAL_SECTION(Pinned.CRITICAL_SECTION),
 84         /** Transient failure: continuation pinned due to native frame */   TRANSIENT_FAIL_PINNED_NATIVE(Pinned.NATIVE),
 85         /** Transient failure: continuation pinned due to a held monitor */ TRANSIENT_FAIL_PINNED_MONITOR(Pinned.MONITOR);
 86 
 87         final Pinned pinned;
 88         private PreemptStatus(Pinned reason) { this.pinned = reason; }
 89         /**
 90          * Whether or not the continuation is pinned.
 91          * @return whether or not the continuation is pinned
 92          **/
 93         public Pinned pinned() { return pinned; }
 94     }
 95 

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


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