void TakeDormantControlNoGC(int currentThreadIndex) { ThreadContext *threadContext = GetCurrentThreadContext(currentThreadIndex); TakeDormantControlNoGC(ref threadContext->gcStates); }
internal static unsafe bool InDormantState(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); return(threadContext == null || fInDormantState(threadContext->gcStates)); }
void TakeMutatorControlNoGC(int currentThreadIndex) { ThreadContext *threadContext = GetCurrentThreadContext(currentThreadIndex); TakeMutatorControlNoGC(threadContext); }
internal static unsafe void EntryIntoManagedSpace() { ThreadContext *currentThreadContext = Processor.GetCurrentThreadContext(); EnsureMutatorControl(currentThreadContext); }
// To be called at the beginning of a thread internal static unsafe void ThreadStart() { ThreadContext *currentThreadContext = Processor.GetCurrentThreadContext(); TakeInitialMutatorControl(currentThreadContext); }
internal static unsafe void RestoreMutatorControlIfNeeded() { ThreadContext *currentThreadContext = Processor.GetCurrentThreadContext(); if (!Transitions.InMutatorState(currentThreadContext)) { // NOTE: There is a window where OtherMutatorControl may be // set simultaneously with OtherGCRequest. When clearing // OtherMutatorControl and setting OtherDormantControl, the // normal thing to do is to check for a GC request, but in // this case it doesn't matter as this code is only run // when an kernel exception is supposed to pass over an // application stack segment. int oldValue, newValue; bool consumedSignal = false; int threadIndex = currentThreadContext->threadIndex; do { oldValue = currentThreadContext->gcStates; if (fUnderGCControl(oldValue)) { Thread.WaitForGCEvent(threadIndex); consumedSignal = true; } newValue = ((oldValue | MutatorState | OtherDormantState) & ~(DormantState | OtherMutatorState)); } while (!CompareAndSwap(ref currentThreadContext->gcStates, newValue, oldValue)); if (consumedSignal) { Thread.SignalGCEvent(threadIndex); } } }
internal static unsafe bool TakeGCControl(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); return(threadContext != null && TakeGCControl(ref threadContext->gcStates)); }
internal static unsafe bool HasGCRequest(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); return(threadContext != null && fHasGCRequest(threadContext->gcStates)); }
internal static unsafe void ThrowProcessUncaughtException() { ThreadContext *context = Processor.GetCurrentThreadContext(); context->uncaughtFlag = false; throw new ProcessUncaughtException(); }
internal static unsafe void ReleaseGCControl(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); if (threadContext != null) { ReleaseGCControl(ref threadContext->gcStates, threadIndex); } }
internal static unsafe void ClearGCRequest(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); if (threadContext != null) { ClearGCRequest(ref threadContext->gcStates, threadIndex); } }
void EnsureDormantControl(int currentThreadIndex) { ThreadContext *threadContext = GetCurrentThreadContext(currentThreadIndex); if (!fInDormantState(threadContext->gcStates)) { TakeDormantControlNoGC(ref threadContext->gcStates); } }
// To be called at the beginning of a thread internal static unsafe void ThreadStart() { ThreadContext *currentThreadContext = Processor.GetCurrentThreadContext(); // The thread has been started in the kernel. We need // to ensure that the transition to application space // is completed properly. EnsureMutatorControlNoGC(currentThreadContext); }
internal static unsafe void ReturnFromManagedSpaceNoCallerTransition() { ThreadContext *currentThreadContext = Processor.GetCurrentThreadContext(); #if SINGULARITY_KERNEL // In Singularity kernel this function is the exit point of a kernel ABI. // If the thread is requested to be aborted, we stop it right here currentThreadContext->thread.ProcessAbortIfRequested(AbortRequestSource.ABINoGCExit); #endif TakeDormantControl(currentThreadContext); }
internal static unsafe void ActivatePreviousStackSegmentLimit() { // To avoid sprinkling [NoStackOverflowCheck] attributes // on too many methods, we manually inline a couple of methods. // ThreadContext *context = Processor.GetCurrentThreadContext(); ThreadRecord * threadRecord = Isa.GetCurrentThread(); ThreadContext *context = (ThreadContext *)threadRecord; StackHead * head = (StackHead *) (context->stackBegin - sizeof(StackHead)); // Isa.StackLimit = head->prevLimit; threadRecord->activeStackLimit = head->prevLimit; }
internal override UIntPtr Callback(UIntPtr param) { unsafe { ThreadContext *newContext = (ThreadContext *)param; // Switch our thread context, synchronizing with the dispatcher as necessary. ProcessorDispatcher.TransferToThreadContext(ref *GetCurrentThreadContext(), ref *newContext); // Resume in the new context. Note that this call does not return. newContext->threadRecord.spill.Resume(); return(0); } }
[NoStackLinkCheckTrans] // We don't want to throw an exception here; // Therefore, we cannot risk allocating stack segments, // and we should only call other NoStackLinkCheck functions (XXX). internal static unsafe UIntPtr CheckKernelProcessBoundary(UIntPtr esp, UIntPtr ebp, Exception exn) { ThreadContext *context = Processor.GetCurrentThreadContext(); CallStack.TransitionRecord *topMarker = context->kernelMarkers; CallStack.TransitionRecord *secondMarker = context->stackMarkers; UIntPtr topMarkerPtr = (UIntPtr)topMarker; // If the top marker is in our frame, we've reached a boundary: if (esp < topMarkerPtr && topMarkerPtr <= ebp) { context->uncaughtFlag = true; Thread.CurrentThread.lastUncaughtException = exn; Processor.GetCurrentThreadContext()->SetKernelMode(); return(1); } else { return(0); } }
void LeaveManagedSpace(ThreadContext *currentThreadContext) { TransferMutatorControl(currentThreadContext); }
internal static unsafe bool InMutatorState(ThreadContext *threadContext) { return(threadContext != null && fInMutatorState(threadContext->gcStates)); }
void SuspendThread(ThreadContext *currentThreadContext) { TakeDormantControl(currentThreadContext); }
void ReturnToManagedSpace(ThreadContext *currentThreadContext) { EnsureMutatorControl(currentThreadContext); }
void EnsureMutatorControlNoGC(ThreadContext *currentThreadContext) { EnsureMutatorControlNoGC(ref currentThreadContext->gcStates, currentThreadContext->threadIndex); }
void ReviveThread(ThreadContext *currentThreadContext) { TakeMutatorControl(currentThreadContext); }
void TakeInitialMutatorControl(ThreadContext *threadContext) { TakeInitialMutatorControl(ref threadContext->gcStates, threadContext->threadIndex); }
void TransferMutatorControl(ThreadContext *currentThreadContext) { TransferMutatorControl(ref currentThreadContext->gcStates, currentThreadContext->threadIndex); }
void TakeMutatorControlNoGC(ThreadContext *threadContext) { TakeMutatorControlNoGC(ref threadContext->gcStates, threadContext->threadIndex); }
internal static unsafe bool InMutatorState(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); return(InMutatorState(threadContext)); }
internal void SetCalleeSaves(ThreadContext *context) { // Placeholder for an override method }
void TakeDormantControl(ThreadContext *threadContext) { TakeDormantControl(ref threadContext->gcStates, threadContext->threadIndex); }
internal static unsafe void TakeDormantControl(int threadIndex) { ThreadContext *threadContext = GetThreadContext(threadIndex); TakeDormantControl(ref threadContext->gcStates, threadIndex); }