void ThreadStore::DetachCurrentThread() { // The thread may not have been initialized because it may never have run managed code before. Thread * pDetachingThread = RawGetCurrentThread(); // The thread was not initialized yet, so it was not attached if (!pDetachingThread->IsInitialized()) { return; } if (!PalDetachThread(pDetachingThread)) { return; } #ifdef STRESS_LOG ThreadStressLog * ptsl = reinterpret_cast<ThreadStressLog *>( pDetachingThread->GetThreadStressLog()); StressLog::ThreadDetach(ptsl); #endif // STRESS_LOG ThreadStore* pTS = GetThreadStore(); ReaderWriterLock::WriteHolder write(&pTS->m_Lock); ASSERT(rh::std::count(pTS->m_ThreadList.Begin(), pTS->m_ThreadList.End(), pDetachingThread) == 1); pTS->m_ThreadList.RemoveFirst(pDetachingThread); pDetachingThread->Destroy(); }
bool StressLog::ReserveStressLogChunks (unsigned chunksToReserve) { Thread *pThread = ThreadStore::GetCurrentThread(); ThreadStressLog* msgs = reinterpret_cast<ThreadStressLog*>(pThread->GetThreadStressLog()); if (msgs == 0) { msgs = CreateThreadStressLog(pThread); if (msgs == 0) return FALSE; } if (chunksToReserve == 0) { chunksToReserve = (theLog.MaxSizePerThread + STRESSLOG_CHUNK_SIZE - 1) / STRESSLOG_CHUNK_SIZE; } long numTries = (long)chunksToReserve - msgs->chunkListLength; for (long i = 0; i < numTries; i++) { msgs->GrowChunkList (); } return msgs->chunkListLength >= (long)chunksToReserve; }
void ThreadStore::DetachCurrentThreadIfHomeFiber() { // // Note: we call this when each *fiber* is destroyed, because we receive that notification outside // of the Loader Lock. This allows us to safely acquire the ThreadStore lock. However, we have to be // extra careful to avoid cleaning up a thread unless the fiber being destroyed is the thread's "home" // fiber, as recorded in AttachCurrentThread. // // The thread may not have been initialized because it may never have run managed code before. Thread * pDetachingThread = RawGetCurrentThread(); ASSERT(_fls_index != FLS_OUT_OF_INDEXES); Thread* pThreadFromCurrentFiber = (Thread*)PalFlsGetValue(_fls_index); if (!pDetachingThread->IsInitialized()) { if (pThreadFromCurrentFiber != NULL) { ASSERT_UNCONDITIONALLY("Detaching a fiber from an unknown thread"); RhFailFast(); } return; } if (pThreadFromCurrentFiber == NULL) { // we've seen this thread, but not this fiber. It must be a "foreign" fiber that was // borrowing this thread. return; } if (pThreadFromCurrentFiber != pDetachingThread) { ASSERT_UNCONDITIONALLY("Detaching a thread from the wrong fiber"); RhFailFast(); } #ifdef STRESS_LOG ThreadStressLog * ptsl = reinterpret_cast<ThreadStressLog *>( pDetachingThread->GetThreadStressLog()); StressLog::ThreadDetach(ptsl); #endif // STRESS_LOG ThreadStore* pTS = GetThreadStore(); ReaderWriterLock::WriteHolder write(&pTS->m_Lock); ASSERT(rh::std::count(pTS->m_ThreadList.Begin(), pTS->m_ThreadList.End(), pDetachingThread) == 1); pTS->m_ThreadList.RemoveFirst(pDetachingThread); pDetachingThread->Destroy(); }
/* static */ void StressLog::LogMsg (unsigned facility, int cArgs, const char* format, ... ) { _ASSERTE ( cArgs >= 0 && cArgs <= StressMsg::maxArgCnt ); va_list Args; va_start(Args, format); Thread *pThread = ThreadStore::GetCurrentThread(); if (pThread == NULL) return; ThreadStressLog* msgs = reinterpret_cast<ThreadStressLog*>(pThread->GetThreadStressLog()); if (msgs == 0) { msgs = CreateThreadStressLog(pThread); if (msgs == 0) return; } msgs->LogMsg (facility, cArgs, format, Args); }