示例#1
0
void DHContext::PrintDeadlock(DHDetails *pDetails, SIZE_T cookie)
{
    ICLRSyncManager *pClrSyncManager = m_pSyncManager->GetCLRSyncManager();

    fprintf(stderr, "A deadlock has occurred; terminating the program. Details below.\r\n");

    // Print details about the attempted acquisition:
    IHostTask *pTask;
    m_pTaskManager->GetCurrentTask((IHostTask**)&pTask);
    fprintf(stderr, "  %x was attempting to acquire %x, which created the cycle\r\n",
        dynamic_cast<DHTask*>(pTask)->GetThreadHandle(), cookie);
    pTask->Release();

    // Now walk through the wait-graph and print details:
    for (DHDetails::iterator walker = pDetails->begin();
        walker != pDetails->end();
        walker++)
    {
        IHostTask *pOwner;
        pClrSyncManager->GetMonitorOwner(walker->second, (IHostTask**)&pOwner);        

        fprintf(stderr, "  %x waits on lock %x (owned by %x)\r\n",
            walker->first->GetThreadHandle(), walker->second,
            dynamic_cast<DHTask*>(pOwner)->GetThreadHandle());

        pOwner->Release();
        walker->first->Release();
    }
}
示例#2
0
STDMETHODIMP DDTaskManager::CreateTask(/* in */ DWORD dwStackSize, /* in */ LPTHREAD_START_ROUTINE pStartAddress, /* in */ PVOID pParameter, /* out */ IHostTask **ppTask) {
    DWORD dwThreadId;
    HANDLE hThread = CreateThread(
        NULL,
        dwStackSize,
        pStartAddress,
        pParameter,
        CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
        &dwThreadId);

    IHostTask* task = new DDTask(hThread);
    if (!task) {
        _ASSERTE(!"Failed to allocate task");
        *ppTask = NULL;
        return E_OUTOFMEMORY;
    }

	m_pThreadMapCrst->Enter();    
	m_pThreadMap->insert(map<DWORD, IHostTask*>::value_type(dwThreadId, task));

	ThreadInfo info;
	info.threadHandle = hThread;
	info.threadId = dwThreadId;
	m_pContext->GetTasksList()->insert(m_pContext->GetTasksList()->begin(), list<ThreadInfo>::value_type(info));		
	m_pThreadMapCrst->Exit();

    task->AddRef();
    *ppTask = task;

    return S_OK;
}
示例#3
0
文件: TaskMgr.cpp 项目: ppatoria/cpp
STDMETHODIMP DHTaskManager::CreateTask(/* in */ DWORD dwStackSize, /* in */ LPTHREAD_START_ROUTINE pStartAddress, /* in */ PVOID pParameter, /* out */ IHostTask **ppTask)
{
    DWORD dwThreadId;
    HANDLE hThread = CreateThread(
        NULL,
        dwStackSize,
        pStartAddress,
        pParameter,
        CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
        &dwThreadId);

    IHostTask* task = new DHTask(this, hThread);
    if (!task)
    {
        _ASSERTE(!"Failed to allocate task");
        *ppTask = NULL;
        return E_OUTOFMEMORY;
    }

    CrstLock crst(m_pThreadMapCrst);
    m_pThreadMap->insert(map<DWORD, IHostTask*>::value_type(dwThreadId, task));
    crst.Exit();

    task->AddRef();
    *ppTask = task;

    return S_OK;
}
示例#4
0
STDMETHODIMP_(VOID) DHContext::EndEnter(SIZE_T cookie)
{
    IHostTask* pCurrentTask;
    m_pTaskManager->GetCurrentTask((IHostTask**)&pCurrentTask);

    // This call is made after the thread has acquired the lock. We simply remove
    // our wait record to indicate that we're no longer waiting for the target lock.
    CrstLock lock(m_pCrst);
    m_pLockWaits->erase(pCurrentTask);
    lock.Exit();

#if LOCK_TRACE
    // If we're tracing, enter a record into the list of currently held locks.
    vector<SIZE_T> *pCurrentLocks = reinterpret_cast<vector<SIZE_T>*>(TlsGetValue(m_dwTlsCurrentLocks));
    if (!pCurrentLocks)
    {
        pCurrentLocks = new vector<SIZE_T>;
        TlsSetValue(m_dwTlsCurrentLocks, pCurrentLocks);
    }
    pCurrentLocks->push_back(cookie);

    // And record the uniquely held locks in the active context.
    CrstLock traceLock(m_pLockTraceCrst);
    for (vector<SIZE_T>::iterator lockWalker = pCurrentLocks->begin();
        lockWalker != pCurrentLocks->end();
        lockWalker++)
    {
        // Obtain the list of locks held for the current lock.
        map<SIZE_T, vector<SIZE_T>*>::iterator traceWalker = m_pLockTrace->find(*lockWalker);
        vector<SIZE_T> *pTrace;
        if (traceWalker == m_pLockTrace->end())
        {
            pTrace = new vector<SIZE_T>;
            m_pLockTrace->insert(map<SIZE_T, vector<SIZE_T>*>::value_type(*lockWalker, pTrace));
        }
        else
        {
            pTrace = traceWalker->second;
        }

        // And ensure all locks held from here on are added.
        for (vector<SIZE_T>::iterator heldLocks(lockWalker);
            heldLocks != pCurrentLocks->end();
            heldLocks++)
        {            
            pTrace->push_back(*heldLocks);
        }
    }
    traceLock.Exit();
#endif

    // This may look strange. We Release the underlying IHostTask twice. But this is an
    // operation paired with TryEnter above, which required a call to GetCurrentTask, the
    // result for which we stashed in our map. Thus, we need to Release once for TryEnter
    // and once for the call just above in EndEnter.
    pCurrentTask->Release();
    pCurrentTask->Release();
}