APIThreadStress::APIThreadStress() { m_threadCount = 0; // Don't "fork" stress threads if (ClrFlsGetValue(TlsIdx_StressThread) == NULL) m_threadCount = s_threadStressCount; if (m_threadCount != 0) { m_setupOK = TRUE; m_hThreadArray = new (nothrow) HANDLE [ m_threadCount ]; if (m_hThreadArray == NULL) m_setupOK = FALSE; else { HANDLE *p = m_hThreadArray; HANDLE *pEnd = p + m_threadCount; while (p < pEnd) { DWORD id; *p = ::CreateThread(NULL, 0, StartThread, this, 0, &id); if (*p == NULL) m_setupOK = FALSE; p++; } } m_syncEvent = ClrCreateManualEvent(FALSE); if (m_syncEvent == INVALID_HANDLE_VALUE) m_setupOK = FALSE; } }
void APIThreadStress::SyncThreadStress() { APIThreadStress *pThis = (APIThreadStress *) ClrFlsGetValue(TlsIdx_StressThread); if (pThis != NULL) { LOG((LF_SYNC, LL_INFO1000, "Syncing stress operation on thread %d\n", GetCurrentThreadId())); ::ResetEvent(pThis->m_syncEvent); if (InterlockedDecrement(&pThis->m_runCount) == 0) ::SetEvent(pThis->m_syncEvent); else WaitForSingleObjectEx(pThis->m_syncEvent, INFINITE, FALSE); InterlockedIncrement(&pThis->m_runCount); LOG((LF_SYNC, LL_INFO1000, "Resuming stress operation on thread %d\n", GetCurrentThreadId())); } }
LogEnv::LogEnv(ICorJitInfo* aCompHnd) : compHnd(aCompHnd), compiler(0) { next = (LogEnv*) ClrFlsGetValue(TlsIdx_JitLogEnv); ClrFlsSetValue(TlsIdx_JitLogEnv, this); }
LogEnv* LogEnv::cur() { return (LogEnv*) ClrFlsGetValue(TlsIdx_JitLogEnv); }
/*********************************************************************************/ /* create a new thread stress log buffer associated with Thread local slot TLSslot, for the Stress log */ ThreadStressLog* StressLog::CreateThreadStressLog() { CONTRACTL { NOTHROW; GC_NOTRIGGER; FORBID_FAULT; SO_TOLERANT; } CONTRACTL_END; static PVOID callerID = NULL; ThreadStressLog* msgs = (ThreadStressLog*) ClrFlsGetValue(theLog.TLSslot); if (msgs != NULL) { return msgs; } if (callerID == ClrTeb::GetFiberPtrId()) { return NULL; } //if we are not allowed to allocate stress log, we should not even try to take the lock if (!StressLogChunk::s_LogChunkHeap || !CanThisThreadCallIntoHost() || IsInCantAllocStressLogRegion ()) { return NULL; }
//***************************************************************************** // The main dll entry point for this module. This routine is called by the // OS when the dll gets loaded. Control is simply deferred to the main code. //***************************************************************************** BOOL WINAPI DbgDllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // Save off the instance handle for later use. switch (dwReason) { case DLL_PROCESS_ATTACH: { #ifndef FEATURE_PAL g_hInst = hInstance; #else int err = PAL_InitializeDLL(); if(err != 0) { return FALSE; } #endif #if defined(_DEBUG) static int BreakOnDILoad = -1; if (BreakOnDILoad == -1) BreakOnDILoad = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_BreakOnDILoad); if (BreakOnDILoad) { _ASSERTE(!"DI Loaded"); } #endif #if defined(LOGGING) { PathString rcFile; WszGetModuleFileName(hInstance, rcFile); LOG((LF_CORDB, LL_INFO10000, "DI::DbgDllMain: load right side support from file '%s'\n", rcFile.GetUnicode())); } #endif #ifdef RSCONTRACTS // alloc a TLS slot DbgRSThread::s_TlsSlot = TlsAlloc(); _ASSERTE(DbgRSThread::s_TlsSlot != TLS_OUT_OF_INDEXES); #endif #if defined(FEATURE_DBGIPC_TRANSPORT_DI) g_pDbgTransportTarget = new (nothrow) DbgTransportTarget(); if (g_pDbgTransportTarget == NULL) return FALSE; if (FAILED(g_pDbgTransportTarget->Init())) return FALSE; #endif // FEATURE_DBGIPC_TRANSPORT_DI } break; case DLL_THREAD_DETACH: { #ifdef STRESS_LOG StressLog::ThreadDetach((ThreadStressLog*) ClrFlsGetValue(TlsIdx_StressLog)); #endif #ifdef RSCONTRACTS // DbgRSThread are lazily created when we call GetThread(), // So we don't need to do anything in DLL_THREAD_ATTACH, // But this is our only chance to destroy the thread object. DbgRSThread * p = DbgRSThread::GetThread(); p->Destroy(); #endif } break; case DLL_PROCESS_DETACH: { #if defined(FEATURE_DBGIPC_TRANSPORT_DI) if (g_pDbgTransportTarget != NULL) { g_pDbgTransportTarget->Shutdown(); delete g_pDbgTransportTarget; g_pDbgTransportTarget = NULL; } #endif // FEATURE_DBGIPC_TRANSPORT_DI #ifdef RSCONTRACTS TlsFree(DbgRSThread::s_TlsSlot); DbgRSThread::s_TlsSlot = TLS_OUT_OF_INDEXES; #endif } break; } return TRUE; }