/// <summary> /// Sets all of the given switch points into the invalid state. /// After this call executes, no thread will observe any of the /// switch points to be in a valid state. /// <para> /// This operation is likely to be expensive and should be used sparingly. /// If possible, it should be buffered for batch processing on sets of switch points. /// </para> /// <para> /// If {@code switchPoints} contains a null element, /// a {@code NullPointerException} will be raised. /// In this case, some non-null elements in the array may be /// processed before the method returns abnormally. /// Which elements these are (if any) is implementation-dependent. /// /// <p style="font-size:smaller;"> /// <em>Discussion:</em> /// For performance reasons, {@code invalidateAll} is not a virtual method /// on a single switch point, but rather applies to a set of switch points. /// Some implementations may incur a large fixed overhead cost /// for processing one or more invalidation operations, /// but a small incremental cost for each additional invalidation. /// In any case, this operation is likely to be costly, since /// other threads may have to be somehow interrupted /// in order to make them notice the updated switch point state. /// However, it may be observed that a single call to invalidate /// several switch points has the same formal effect as many calls, /// each on just one of the switch points. /// /// <p style="font-size:smaller;"> /// <em>Implementation Note:</em> /// Simple implementations of {@code SwitchPoint} may use /// a private <seealso cref="MutableCallSite"/> to publish the state of a switch point. /// In such an implementation, the {@code invalidateAll} method can /// simply change the call site's target, and issue one call to /// <seealso cref="MutableCallSite#syncAll synchronize"/> all the /// private call sites. /// /// </para> /// </summary> /// <param name="switchPoints"> an array of call sites to be synchronized </param> /// <exception cref="NullPointerException"> if the {@code switchPoints} array reference is null /// or the array contains a null </exception> public static void InvalidateAll(SwitchPoint[] switchPoints) { if (switchPoints.Length == 0) { return; } MutableCallSite[] sites = new MutableCallSite[switchPoints.Length]; for (int i = 0; i < switchPoints.Length; i++) { SwitchPoint spt = switchPoints[i]; if (spt == null) // MSC.syncAll will trigger a NPE { break; } sites[i] = spt.Mcs; spt.Mcs.Target = K_false; } MutableCallSite.SyncAll(sites); }
/// <summary> /// Creates a new switch point. /// </summary> public SwitchPoint() { this.Mcs = new MutableCallSite(K_true); this.McsInvoker = Mcs.DynamicInvoker(); }