// static void ThreadStore::AttachCurrentThread(bool fAcquireThreadStoreLock) { // // step 1: ThreadStore::InitCurrentThread // step 2: add this thread to the ThreadStore // // The thread has been constructed, during which some data is initialized (like which RuntimeInstance the // thread belongs to), but it hasn't been added to the thread store because doing so takes a lock, which // we want to avoid at construction time because the loader lock is held then. Thread * pAttachingThread = RawGetCurrentThread(); // On CHK build, validate that our GetThread assembly implementation matches the C++ implementation using // TLS. CreateCurrentThreadBuffer(); ASSERT(_fls_index != FLS_OUT_OF_INDEXES); Thread* pThreadFromCurrentFiber = (Thread*)PalFlsGetValue(_fls_index); if (pAttachingThread->IsInitialized()) { if (pThreadFromCurrentFiber != pAttachingThread) { ASSERT_UNCONDITIONALLY("Multiple fibers encountered on a single thread"); RhFailFast(); } return; } if (pThreadFromCurrentFiber != NULL) { ASSERT_UNCONDITIONALLY("Multiple threads encountered from a single fiber"); RhFailFast(); } // // Init the thread buffer // pAttachingThread->Construct(); ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); ThreadStore* pTS = GetThreadStore(); ReaderWriterLock::WriteHolder write(&pTS->m_Lock, fAcquireThreadStoreLock); // // Set thread state to be attached // ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); pAttachingThread->m_ThreadStateFlags = Thread::TSF_Attached; pTS->m_ThreadList.PushHead(pAttachingThread); // // Associate the current fiber with the current thread. This makes the current fiber the thread's "home" // fiber. This fiber is the only fiber allowed to execute managed code on this thread. When this fiber // is destroyed, we consider the thread to be destroyed. // PalFlsSetValue(_fls_index, pAttachingThread); }
// static void ThreadStore::AttachCurrentThread(bool fAcquireThreadStoreLock) { // // step 1: ThreadStore::InitCurrentThread // step 2: add this thread to the ThreadStore // // The thread has been constructed, during which some data is initialized (like which RuntimeInstance the // thread belongs to), but it hasn't been added to the thread store because doing so takes a lock, which // we want to avoid at construction time because the loader lock is held then. Thread * pAttachingThread = RawGetCurrentThread(); // On CHK build, validate that our GetThread assembly implementation matches the C++ implementation using // TLS. CreateCurrentThreadBuffer(); // The thread was already initialized, so it is already attached if (pAttachingThread->IsInitialized()) { return; } PalAttachThread(pAttachingThread); // // Init the thread buffer // pAttachingThread->Construct(); ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); // The runtime holds the thread store lock for the duration of thread suspension for GC, so let's check to // see if that's going on and, if so, use a proper wait instead of the RWL's spinning. NOTE: when we are // called with fAcquireThreadStoreLock==false, we are being called in a situation where the GC is trying to // init a GC thread, so we must honor the flag to mean "do not block on GC" or else we will deadlock. if (fAcquireThreadStoreLock && (RhpTrapThreads != 0)) RedhawkGCInterface::WaitForGCCompletion(); ThreadStore* pTS = GetThreadStore(); ReaderWriterLock::WriteHolder write(&pTS->m_Lock, fAcquireThreadStoreLock); // // Set thread state to be attached // ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); pAttachingThread->m_ThreadStateFlags = Thread::TSF_Attached; pTS->m_ThreadList.PushHead(pAttachingThread); }
// static void ThreadStore::AttachCurrentThread(bool fAcquireThreadStoreLock) { // // step 1: ThreadStore::InitCurrentThread // step 2: add this thread to the ThreadStore // // The thread has been constructed, during which some data is initialized (like which RuntimeInstance the // thread belongs to), but it hasn't been added to the thread store because doing so takes a lock, which // we want to avoid at construction time because the loader lock is held then. Thread * pAttachingThread = RawGetCurrentThread(); // On CHK build, validate that our GetThread assembly implementation matches the C++ implementation using // TLS. CreateCurrentThreadBuffer(); // The thread was already initialized, so it is already attached if (pAttachingThread->IsInitialized()) { return; } PalAttachThread(pAttachingThread); // // Init the thread buffer // pAttachingThread->Construct(); ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); ThreadStore* pTS = GetThreadStore(); ReaderWriterLock::WriteHolder write(&pTS->m_Lock, fAcquireThreadStoreLock); // // Set thread state to be attached // ASSERT(pAttachingThread->m_ThreadStateFlags == Thread::TSF_Unknown); pAttachingThread->m_ThreadStateFlags = Thread::TSF_Attached; pTS->m_ThreadList.PushHead(pAttachingThread); }