/*non-public*/ internal static bool ShouldBeInitialized(MemberName member) { switch (member.ReferenceKind) { case REF_invokeStatic: case REF_getStatic: case REF_putStatic: case REF_newInvokeSpecial: break; default: // No need to initialize the class on this kind of member. return(false); } Class cls = member.DeclaringClass; if (cls == typeof(ValueConversions) || cls == typeof(MethodHandleImpl) || cls == typeof(Invokers)) { // These guys have lots of <clinit> DMH creation but we know // the MHs will not be used until the system is booted. return(false); } if (VerifyAccess.isSamePackage(typeof(MethodHandle), cls) || VerifyAccess.isSamePackage(typeof(ValueConversions), cls)) { // It is a system class. It is probably in the process of // being initialized, but we will help it along just to be safe. if (UNSAFE.shouldBeInitialized(cls)) { UNSAFE.ensureClassInitialized(cls); } return(false); } return(UNSAFE.shouldBeInitialized(cls)); }
/// <summary> /// Tries to unlink a timed-out or interrupted wait node to avoid /// accumulating garbage. Internal nodes are simply unspliced /// without CAS since it is harmless if they are traversed anyway /// by releasers. To avoid effects of unsplicing from already /// removed nodes, the list is retraversed in case of an apparent /// race. This is slow when there are a lot of nodes, but we don't /// expect lists to be long enough to outweigh higher-overhead /// schemes. /// </summary> private void RemoveWaiter(WaitNode node) { if (node != null) { node.Thread = null; for (;;) // restart on removeWaiter race { for (WaitNode pred = null, q = Waiters, s; q != null; q = s) { s = q.next; if (q.thread != null) { pred = q; } else if (pred != null) { pred.next = s; if (pred.thread == null) // check for race { goto retryContinue; } } else if (!UNSAFE.compareAndSwapObject(this, WaitersOffset, q, s)) { goto retryContinue; } } break; retryContinue :; } retryBreak :; } }
/// <summary> /// Makes available the permit for the given thread, if it /// was not already available. If the thread was blocked on /// {@code park} then it will unblock. Otherwise, its next call /// to {@code park} is guaranteed not to block. This operation /// is not guaranteed to have any effect at all if the given /// thread has not been started. /// </summary> /// <param name="thread"> the thread to unpark, or {@code null}, in which case /// this operation has no effect </param> public static void Unpark(Thread thread) { if (thread != null) { UNSAFE.unpark(thread); } }
/// <summary> /// Removes and signals all waiting threads, invokes done(), and /// nulls out callable. /// </summary> private void FinishCompletion() { // assert state > COMPLETING; for (WaitNode q; (q = Waiters) != null;) { if (UNSAFE.compareAndSwapObject(this, WaitersOffset, q, null)) { for (;;) { Thread t = q.thread; if (t != null) { q.thread = null; LockSupport.Unpark(t); } WaitNode next = q.next; if (next == null) { break; } q.next = null; // unlink to help gc q = next; } break; } } Done(); Callable = null; // to reduce footprint }
/// <summary> /// Disables the current thread for thread scheduling purposes, for up to /// the specified waiting time, unless the permit is available. /// /// <para>If the permit is available then it is consumed and the call /// returns immediately; otherwise the current thread becomes disabled /// for thread scheduling purposes and lies dormant until one of four /// things happens: /// /// <ul> /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> /// the current thread; or /// /// <li>The specified waiting time elapses; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread, or the elapsed time /// upon return. /// /// </para> /// </summary> /// <param name="nanos"> the maximum number of nanoseconds to wait </param> public static void ParkNanos(long nanos) { if (nanos > 0) { UNSAFE.park(false, nanos); } }
public virtual bool Cancel(bool mayInterruptIfRunning) { if (!(State == NEW && UNSAFE.compareAndSwapInt(this, StateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) { return(false); } try // in case call to interrupt throws exception { if (mayInterruptIfRunning) { try { Thread t = Runner; if (t != null) { t.Interrupt(); } } // final state finally { UNSAFE.putOrderedInt(this, StateOffset, INTERRUPTED); } } } finally { FinishCompletion(); } return(true); }
private static bool CheckInitialized(MemberName member) { Class defc = member.DeclaringClass; WeakReference <Thread> @ref = EnsureInitialized.INSTANCE.Get(defc); if (@ref == null) { return(true); // the final state } Thread clinitThread = @ref.get(); // Somebody may still be running defc.<clinit>. if (clinitThread == Thread.CurrentThread) { // If anybody is running defc.<clinit>, it is this thread. if (UNSAFE.shouldBeInitialized(defc)) { // Yes, we are running it; keep the barrier for now. return(false); } } else { // We are in a random thread. Block. UNSAFE.ensureClassInitialized(defc); } assert(!UNSAFE.shouldBeInitialized(defc)); // put it into the final state EnsureInitialized.INSTANCE.Remove(defc); return(true); }
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException private void ReadObject(ObjectInputStream @in) { // Don't call defaultReadObject() ObjectInputStream.GetField oisFields = @in.ReadFields(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final String oisHostname = (String)oisFields.get("hostname", null); String oisHostname = (String)oisFields.Get("hostname", null); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null); InetAddress oisAddr = (InetAddress)oisFields.Get("addr", null); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final int oisPort = oisFields.get("port", -1); int oisPort = oisFields.Get("port", -1); // Check that our invariants are satisfied CheckPort(oisPort); if (oisHostname == null && oisAddr == null) { throw new InvalidObjectException("hostname and addr " + "can't both be null"); } InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname, oisAddr, oisPort); UNSAFE.putObject(this, FIELDS_OFFSET, h); }
/// <summary> /// Disables the current thread for thread scheduling purposes unless the /// permit is available. /// /// <para>If the permit is available then it is consumed and the call returns /// immediately; otherwise /// the current thread becomes disabled for thread scheduling /// purposes and lies dormant until one of three things happens: /// /// <ul> /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> /// the current thread; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread upon return. /// /// </para> /// </summary> /// <param name="blocker"> the synchronization object responsible for this /// thread parking /// @since 1.6 </param> public static void Park(Object blocker) { Thread t = Thread.CurrentThread; SetBlocker(t, blocker); UNSAFE.park(false, 0L); SetBlocker(t, null); }
/// <summary> /// Disables the current thread for thread scheduling purposes, until /// the specified deadline, unless the permit is available. /// /// <para>If the permit is available then it is consumed and the call /// returns immediately; otherwise the current thread becomes disabled /// for thread scheduling purposes and lies dormant until one of four /// things happens: /// /// <ul> /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> the /// current thread; or /// /// <li>The specified deadline passes; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread, or the current time /// upon return. /// /// </para> /// </summary> /// <param name="blocker"> the synchronization object responsible for this /// thread parking </param> /// <param name="deadline"> the absolute time, in milliseconds from the Epoch, /// to wait until /// @since 1.6 </param> public static void ParkUntil(Object blocker, long deadline) { Thread t = Thread.CurrentThread; SetBlocker(t, blocker); UNSAFE.park(true, deadline); SetBlocker(t, null); }
/// <summary> /// Returns the blocker object supplied to the most recent /// invocation of a park method that has not yet unblocked, or null /// if not blocked. The value returned is just a momentary /// snapshot -- the thread may have since unblocked or blocked on a /// different blocker object. /// </summary> /// <param name="t"> the thread </param> /// <returns> the blocker </returns> /// <exception cref="NullPointerException"> if argument is null /// @since 1.6 </exception> public static Object GetBlocker(Thread t) { if (t == null) { throw new NullPointerException(); } return(UNSAFE.getObjectVolatile(t, ParkBlockerOffset)); }
/// <summary> /// Pseudo-randomly advances and records the given probe value for the /// given thread. /// Duplicated from ThreadLocalRandom because of packaging restrictions. /// </summary> internal static int AdvanceProbe(int probe) { probe ^= probe << 13; // xorshift probe ^= (int)((uint)probe >> 17); probe ^= probe << 5; UNSAFE.putInt(Thread.CurrentThread, PROBE, probe); return(probe); }
/// <summary> /// Sets the result of this future to the given value unless /// this future has already been set or has been cancelled. /// /// <para>This method is invoked internally by the <seealso cref="#run"/> method /// upon successful completion of the computation. /// /// </para> /// </summary> /// <param name="v"> the value </param> protected internal virtual void Set(V v) { if (UNSAFE.compareAndSwapInt(this, StateOffset, NEW, COMPLETING)) { Outcome = v; UNSAFE.putOrderedInt(this, StateOffset, NORMAL); // final state FinishCompletion(); } }
/// <summary> /// Disables the current thread for thread scheduling purposes, for up to /// the specified waiting time, unless the permit is available. /// /// <para>If the permit is available then it is consumed and the call /// returns immediately; otherwise the current thread becomes disabled /// for thread scheduling purposes and lies dormant until one of four /// things happens: /// /// <ul> /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> /// the current thread; or /// /// <li>The specified waiting time elapses; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread, or the elapsed time /// upon return. /// /// </para> /// </summary> /// <param name="blocker"> the synchronization object responsible for this /// thread parking </param> /// <param name="nanos"> the maximum number of nanoseconds to wait /// @since 1.6 </param> public static void ParkNanos(Object blocker, long nanos) { if (nanos > 0) { Thread t = Thread.CurrentThread; SetBlocker(t, blocker); UNSAFE.park(false, nanos); SetBlocker(t, null); } }
protected internal override WeakReference <Thread> ComputeValue(Class type) { UNSAFE.ensureClassInitialized(type); if (UNSAFE.shouldBeInitialized(type)) // If the previous call didn't block, this can happen. // We are executing inside <clinit>. { return(new WeakReference <>(Thread.CurrentThread)); } return(null); }
/// <summary> /// Awaits completion or aborts on interrupt or timeout. /// </summary> /// <param name="timed"> true if use timed waits </param> /// <param name="nanos"> time to wait, if timed </param> /// <returns> state upon completion </returns> //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: private int awaitDone(boolean timed, long nanos) throws InterruptedException private int AwaitDone(bool timed, long nanos) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final long deadline = timed ? System.nanoTime() + nanos : 0L; long deadline = timed ? System.nanoTime() + nanos : 0L; WaitNode q = null; bool queued = false; for (;;) { if (Thread.Interrupted()) { RemoveWaiter(q); throw new InterruptedException(); } int s = State; if (s > COMPLETING) { if (q != null) { q.Thread = null; } return(s); } else if (s == COMPLETING) // cannot time out yet { Thread.@yield(); } else if (q == null) { q = new WaitNode(); } else if (!queued) { queued = UNSAFE.compareAndSwapObject(this, WaitersOffset, q.Next = Waiters, q); } else if (timed) { nanos = deadline - System.nanoTime(); if (nanos <= 0L) { RemoveWaiter(q); return(State); } LockSupport.ParkNanos(this, nanos); } else { LockSupport.Park(this); } } }
/// <summary> /// Returns the pseudo-randomly initialized or updated secondary seed. /// Copied from ThreadLocalRandom due to package access restrictions. /// </summary> internal static int NextSecondarySeed() { int r; Thread t = Thread.CurrentThread; if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) { r ^= r << 13; // xorshift r ^= (int)((uint)r >> 17); r ^= r << 5; } else if ((r = java.util.concurrent.ThreadLocalRandom.Current().NextInt()) == 0) { r = 1; // avoid zero } UNSAFE.putInt(t, SECONDARY, r); return(r); }
public virtual void Run() { if (State != NEW || !UNSAFE.compareAndSwapObject(this, RunnerOffset, null, Thread.CurrentThread)) { return; } try { Callable <V> c = Callable; if (c != null && State == NEW) { V result; bool ran; try { result = c.Call(); ran = true; } catch (Throwable ex) { result = null; ran = false; Exception = ex; } if (ran) { Set(result); } } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() Runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = State; if (s >= INTERRUPTING) { HandlePossibleCancellationInterrupt(s); } } }
static CallSite() { MethodHandleImpl.InitStatics(); try { GET_TARGET = IMPL_LOOKUP.findVirtual(typeof(CallSite), "getTarget", MethodType.MethodType(typeof(MethodHandle))); THROW_UCS = IMPL_LOOKUP.findStatic(typeof(CallSite), "uninitializedCallSite", MethodType.MethodType(typeof(Object), typeof(Object[]))); } catch (ReflectiveOperationException e) { throw newInternalError(e); } try { TARGET_OFFSET = UNSAFE.objectFieldOffset(typeof(CallSite).getDeclaredField("target")); } catch (Exception ex) { throw new Error(ex); } }
/// <summary> /// Executes the computation without setting its result, and then /// resets this future to initial state, failing to do so if the /// computation encounters an exception or is cancelled. This is /// designed for use with tasks that intrinsically execute more /// than once. /// </summary> /// <returns> {@code true} if successfully run and reset </returns> protected internal virtual bool RunAndReset() { if (State != NEW || !UNSAFE.compareAndSwapObject(this, RunnerOffset, null, Thread.CurrentThread)) { return(false); } bool ran = false; int s = State; try { Callable <V> c = Callable; if (c != null && s == NEW) { try { c.Call(); // don't set result ran = true; } catch (Throwable ex) { Exception = ex; } } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() Runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts s = State; if (s >= INTERRUPTING) { HandlePossibleCancellationInterrupt(s); } } return(ran && s == NEW); }
internal virtual void LazySetNext(Node <E> val) { UNSAFE.putOrderedObject(this, NextOffset, val); }
/// <summary> /// Disables the current thread for thread scheduling purposes, until /// the specified deadline, unless the permit is available. /// /// <para>If the permit is available then it is consumed and the call /// returns immediately; otherwise the current thread becomes disabled /// for thread scheduling purposes and lies dormant until one of four /// things happens: /// /// <ul> /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> /// the current thread; or /// /// <li>The specified deadline passes; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread, or the current time /// upon return. /// /// </para> /// </summary> /// <param name="deadline"> the absolute time, in milliseconds from the Epoch, /// to wait until </param> public static void ParkUntil(long deadline) { UNSAFE.park(true, deadline); }
/// <summary> /// Disables the current thread for thread scheduling purposes unless the /// permit is available. /// /// <para>If the permit is available then it is consumed and the call /// returns immediately; otherwise the current thread becomes disabled /// for thread scheduling purposes and lies dormant until one of three /// things happens: /// /// <ul> /// /// <li>Some other thread invokes <seealso cref="#unpark unpark"/> with the /// current thread as the target; or /// /// <li>Some other thread <seealso cref="Thread#interrupt interrupts"/> /// the current thread; or /// /// <li>The call spuriously (that is, for no reason) returns. /// </ul> /// /// </para> /// <para>This method does <em>not</em> report which of these caused the /// method to return. Callers should re-check the conditions which caused /// the thread to park in the first place. Callers may also determine, /// for example, the interrupt status of the thread upon return. /// </para> /// </summary> public static void Park() { UNSAFE.park(false, 0L); }
/// <summary> /// Constructs a new node. Uses relaxed write because item can /// only be seen after publication via casNext. /// </summary> internal Node(E item) { UNSAFE.putObject(this, ItemOffset, item); }
internal virtual bool CasItem(E cmp, E val) { return(UNSAFE.compareAndSwapObject(this, ItemOffset, cmp, val)); }
/// <summary> /// CASes the cellsBusy field from 0 to 1 to acquire lock. /// </summary> internal bool CasCellsBusy() { return(UNSAFE.compareAndSwapInt(this, CELLSBUSY, 0, 1)); }
internal virtual bool CasNext(Node <E> cmp, Node <E> val) { return(UNSAFE.compareAndSwapObject(this, NextOffset, cmp, val)); }
private static void SetBlocker(Thread t, Object arg) { // Even though volatile, hotspot doesn't need a write barrier here. UNSAFE.putObject(t, ParkBlockerOffset, arg); }
/*non-public*/ //JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET: //ORIGINAL LINE: static Object allocateInstance(Object mh) throws InstantiationException internal static Object AllocateInstance(Object mh) { Constructor dmh = (Constructor)mh; return(UNSAFE.allocateInstance(dmh.InstanceClass)); }
/// <summary> /// CASes the base field. /// </summary> internal bool CasBase(long cmp, long val) { return(UNSAFE.compareAndSwapLong(this, BASE, cmp, val)); }