CProcess* CMigrationInfo::FindProcessToMigrateOnMemOverflow(CNode* i_sourceNode, CNode* i_destinationNode) { // trying to move the process that uses the highest amount of memory from the source node to the destination node // that process must also have enough memory on the destination node so this node does not overflow CProcess* returnValue = NULL; double sourceNodeMemSize = i_sourceNode->GetMemSize(); double sourceNodeFreeMem = i_sourceNode->GetFreeMem(); double destNodeMemSize = i_destinationNode->GetMemSize(); double destNodeFreeMem = i_destinationNode->GetFreeMem(); double largestProcessMem = 0; double destinationIndex = 0; for (uint32_t i = 0; i < i_sourceNode->GetProcessCount(); ++i) { CProcess* currentProcess = i_sourceNode->GetProcess(i); double processMemRequired = currentProcess->GetMemoryRequired(); if (processMemRequired > largestProcessMem) { if ( (1.0 * (sourceNodeMemSize - sourceNodeFreeMem - processMemRequired) / sourceNodeMemSize) < CMasterSingleton::GetInstance()->GetMemoryMigrationTreshold() && (1.0 * (destNodeMemSize- destNodeFreeMem + processMemRequired) / destNodeMemSize) < CMasterSingleton::GetInstance()->GetMemoryMigrationTreshold()) { largestProcessMem = processMemRequired; returnValue = i_sourceNode->GetProcess(i); } } } return returnValue; }
// override // Bit of a hack here to ensure a reasonable function for the sentrans // process, based on what sequence its in. If we're in a transfer // sequence, then that must be the goal. CProcess* CSentransProcessTemplate::createProcess(int iSeqFunctionCode, SFMFile* pInputFile) { CProcess* p = CProcessTemplate::createProcess(iSeqFunctionCode, pInputFile); ASSERTX(p->IsKindOf(RUNTIME_CLASS(CSentransProcess))); if(-1 != iSeqFunctionCode) { switch(iSeqFunctionCode) { case CProcess::kAnalysis: // note that the user can change this to kAdjustSrcAnalysis. THis // is just the default. ((CSentransProcess*)p)->m_iFunction = CSentransProcess::kDisambig; break; case CProcess::kInterlinear: ((CSentransProcess*)p)->m_iFunction = CSentransProcess::kAdjustSrcGlossing; break; case CProcess::kTransfer: ((CSentransProcess*)p)->m_iFunction = CSentransProcess::kTransfer; break; default: ASSERTX(FALSE); } // else leave it to the default } return p; }
//---------------------------------------- // input polling void CLogPanel::OnIdle(wxIdleEvent& event) { CMapProcess::iterator it; wxObArray processToRemove(false); CProcess* process = NULL; for (it = m_processes.begin() ; it != m_processes.end() ; it++) { process = GetProcess(it); if (process != NULL) { if ( (process->IsKilled()) || (process->IsEnded()) ) { GetTasklist()->RemoveProcess(process); processToRemove.Insert(process); m_processToRemove.Insert(process); } else if ( process->HasInput() ) { event.RequestMore(); } } } for (uint32_t i = 0 ; i < processToRemove.size() ; i ++) { process = dynamic_cast<CProcess*>(processToRemove[i]); RemoveProcess(process->GetName()); //delete process; process = NULL; } }
void CSchedule::Start() { if (!m_summer.Initialize()) { return ; } for (int i=0; i< 1; i++) { CProcess * p = new CProcess(); if (p->Start()) { m_process.push_back(p); } } if (g_startType == 0) { if (m_accept.OpenAccept(g_remoteIP.c_str(), g_remotePort)) { LOGI("open server port [" << g_remotePort << "] success"); } CTcpSocketPtr s(new zsummer::network::CTcpSocket()); s->Initialize(m_process[m_iCurProcess]->GetZSummer()); m_accept.DoAccept(s, std::bind(&CSchedule::OnAccept, this, std::placeholders::_1, std::placeholders::_2, m_process[m_iCurProcess])); } else { doConnect(g_maxClient); } m_thread = std::thread(std::bind(&CSchedule::Run, this)); }
void CDlgProcessSequence::OnDblclkProcessList(NMHDR* pNMHDR, LRESULT* pResult) { HWND hWnd = pNMHDR->hwndFrom; CListCtrl* pCtrl = (CListCtrl*) CWnd::FromHandle(hWnd); POINT pointScreen; DWORD dwPos; dwPos = GetMessagePos(); pointScreen.x = LOWORD (dwPos); pointScreen.y = HIWORD (dwPos); ::MapWindowPoints(NULL, hWnd,&pointScreen, 1); CPoint pt_local(pointScreen); pt_local.x = 5; // it likes clicks on the left edge, not in the middle, so fake it UINT flags; int i = pCtrl->HitTest(pt_local, &flags) ; if(i>=0) { // could be a subclass of CWListEntry, an evironment row, or a comment row CProcess *pProc = (CProcess *) pCtrl->GetItemData(i); if(pProc) #ifndef hab231 { pProc->doEditDialog(m_iFunctionCode); populateListCtrl(); } #else // hab231 pProc->doEditDialog(m_iFunctionCode); #endif // hab231 } *pResult = 0; }
CProcess* CProcessTemplate::createProcess(int iSeqFunctionCode, SFMFile* pInputFile) { CProcess* pObject = (CProcess*)m_pClass->CreateObject(); if(pObject) { ASSERTX( pObject->IsKindOf( m_pClass )); if(pInputFile) pObject->readParametersFromSFMFile(pInputFile); } else AfxMessageBox("Couldn't create the process.\n"); return pObject; }
void CDlgProcessSequence::OnProperties() { // 1) figure out which process is selected CProcess* pProc = getFirstSelectedProcess(); if (!pProc) return; // 2) tell that process to put up the edit dialog if (pProc->doEditDialog(m_iFunctionCode)) { m_bModified=TRUE; // these two often don't work SetRedraw(TRUE); Invalidate(); // may have changed something that effects the display } }
void CDlgProcessSequence::OnGetdispinfoProcessList(NMHDR* pNMHDR, LRESULT* pResult) { LV_DISPINFO* pnmv = (LV_DISPINFO*)pNMHDR; // TODO: Add your control notification handler code here *pResult = 0; // Provide the item or subitem's text, if requested. if (pnmv->item.mask & LVIF_TEXT) { CProcess* pProc = (CProcess *) (pnmv->item.lParam); lstrcpy(pnmv->item.pszText, pProc->getListCtrlText(pnmv->item.iSubItem)); } *pResult = 0; // THIS WAS PUT HERE BY THE WIZARD }
void CSchedule::doConnect(unsigned int maxClient) { for (unsigned int i = 1; i <= maxClient; i++) { CTcpSocketPtr s(new zsummer::network::CTcpSocket()); CProcess * proc = m_process[m_iCurProcess]; s->Initialize(proc->GetZSummer()); proc->Post(std::bind(&CProcess::RecvSocketPtr, proc, s)); m_iCurProcess++; m_iCurProcess = m_iCurProcess%(int)m_process.size(); if (i >= 100 && maxClient > 100) { m_summer.CreateTimer(1000, std::bind(&CSchedule::doConnect, this, maxClient - i)); break; } } }
void CJobObject::AssignProcess(CProcess& Process) { BOOL bRet; CMutex::CEnter MutexEnter(m_Mutex); bRet = AssignProcessToJobObject(GetHandle(), Process.GetHandle()); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } }
//-------------------------------------------------------------------------------- bool CJob::ContainsProcess( CProcess& Process, int& iResult ) { _WINQ_FCONTEXT( "CJob::ContainsProcess" ); bool bResult = false; __QOR_PROTECT { bResult = CKernel32::IsProcessInJob( const_cast< void* >( Process.ProcessHandle().Use() ), m_Handle.Use(), &iResult ) ? true : false; }__QOR_ENDPROTECT return bResult; }
//telo provadeciho vlakna procesu DWORD CProcess::Start() { Run(); // popis aktivnich fazi procesu // po jejich vykonani: CProcess* next; if (event != NULL) // pokud ma proces zaznam o udalosti { next=NextEv(); event->Out(); delete(event); // odstrani jej event = NULL; if (next!=NULL) // v SQS je zaznam o dalsim procesu // tady nekde prerusit pri krokovani next->Resume(); // aktivuj tento proces } terminated = true; // oznac proces za ukonceny return 0; // a ukonci proceduru vlakna }
void CUser::LogonCurrentUser(void) { CTrace::CEnter Enter(CTrace::Layer::KERNEL, L"User::LogonCurrentUser()"); static const DWORD dwMaxUsername = 4096; CProcess ThisProcess; DWORD dwLengthUsername = dwMaxUsername; WCHAR szUsername[dwMaxUsername]; BOOL bRet; HANDLE hToken; bRet = OpenProcessToken(ThisProcess.GetHandle(), TOKEN_ALL_ACCESS, &hToken); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } else { SetHandle(hToken); } bRet = ::GetUserName(szUsername, &dwLengthUsername); if (bRet == 0) { throw CCodineException(CError::GetErrorMessage(GetLastError()), __FILE__, __LINE__); } m_Username = szUsername; }
static HRESULT Call7zGui(const UString ¶ms, // LPCWSTR curDir, bool waitFinish, NSynchronization::CBaseEvent *event) { UString imageName = fs2us(NWindows::NDLL::GetModuleDirPrefix()); imageName.AddAscii(k7zGui); CProcess process; WRes res = process.Create(imageName, params, NULL); // curDir); if (res != 0) { ErrorMessageHRESULT(res, imageName); return res; } if (waitFinish) process.Wait(); else if (event != NULL) { HANDLE handles[] = { process, *event }; ::WaitForMultipleObjects(ARRAY_SIZE(handles), handles, FALSE, INFINITE); } return S_OK; }
static HRESULT StartEditApplication(const UString &path, HWND window, CProcess &process) { UString command; ReadRegEditor(command); if (command.IsEmpty()) { #ifdef UNDER_CE command = L"\\Windows\\"; #else if (!MyGetWindowsDirectory(command)) return 0; NFile::NName::NormalizeDirPathPrefix(command); #endif command += L"notepad.exe"; } HRESULT res = process.Create(command, GetQuotedString(path), NULL); if (res != SZ_OK) ::MessageBoxW(window, LangString(IDS_CANNOT_START_EDITOR, 0x03020282), L"7-Zip", MB_OK | MB_ICONSTOP); return res; }
static HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process) { UINT32 result; #ifndef _UNICODE if (g_IsNT) { SHELLEXECUTEINFOW execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; execInfo.lpFile = path; execInfo.lpParameters = NULL; execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir; execInfo.nShow = SW_SHOWNORMAL; execInfo.hProcess = 0; ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP) ::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW"); if (shellExecuteExW == 0) return 0; shellExecuteExW(&execInfo); result = (UINT32)(UINT_PTR)execInfo.hInstApp; process.Attach(execInfo.hProcess); } else #endif { SHELLEXECUTEINFO execInfo; execInfo.cbSize = sizeof(execInfo); execInfo.fMask = SEE_MASK_NOCLOSEPROCESS #ifndef UNDER_CE | SEE_MASK_FLAG_DDEWAIT #endif ; execInfo.hwnd = NULL; execInfo.lpVerb = NULL; const CSysString sysPath = GetSystemString(path); const CSysString sysDir = GetSystemString(dir); execInfo.lpFile = sysPath; execInfo.lpParameters = NULL; execInfo.lpDirectory = #ifdef UNDER_CE NULL #else sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir #endif ; execInfo.nShow = SW_SHOWNORMAL; execInfo.hProcess = 0; ::ShellExecuteEx(&execInfo); result = (UINT32)(UINT_PTR)execInfo.hInstApp; process.Attach(execInfo.hProcess); } if (result <= 32) { switch(result) { case SE_ERR_NOASSOC: ::MessageBoxW(window, NError::MyFormatMessageW(::GetLastError()), // L"There is no application associated with the given file name extension", L"7-Zip", MB_OK | MB_ICONSTOP); } } return S_OK; }
//-------------------------------------------------------------------------------- bool CJob::AssignProcess( CProcess& Process ) { _WINQ_FCONTEXT( "CJob::AssignProcess" ); bool bResult = false; __QOR_PROTECT { bResult = CKernel32::AssignProcessToJobObject( m_Handle.Use(), const_cast< void* >( Process.ProcessHandle().Use() ) ) ? true : false; }__QOR_ENDPROTECT return bResult; }
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode) { const UString name = GetItemName(index); if (IsNameVirus(name)) { MessageBoxErrorLang(IDS_VIRUS, 0x03020284); return; } CMyComPtr<IFolderOperations> folderOperations; if (_folder.QueryInterface(IID_IFolderOperations, &folderOperations) != S_OK) { MessageBoxErrorLang(IDS_OPERATION_IS_NOT_SUPPORTED, 0x03020208); return; } bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name)); UString fullVirtPath = _currentFolderPrefix + name; NFile::NDirectory::CTempDirectoryW tempDirectory; tempDirectory.Create(kTempDirPrefix); UString tempDir = tempDirectory.GetPath(); UString tempDirNorm = tempDir; NFile::NName::NormalizeDirPathPrefix(tempDirNorm); UString tempFilePath = tempDirNorm + GetCorrectFsPath(name); CTempFileInfo tempFileInfo; tempFileInfo.ItemName = name; tempFileInfo.FolderPath = tempDir; tempFileInfo.FilePath = tempFilePath; tempFileInfo.NeedDelete = true; if (tryAsArchive) { CMyComPtr<IInArchiveGetStream> getStream; _folder.QueryInterface(IID_IInArchiveGetStream, &getStream); if (getStream) { CMyComPtr<ISequentialInStream> subSeqStream; getStream->GetStream(index, &subSeqStream); if (subSeqStream) { CMyComPtr<IInStream> subStream; subSeqStream.QueryInterface(IID_IInStream, &subStream); if (subStream) { bool encrypted; if (OpenItemAsArchive(subStream, tempFileInfo, fullVirtPath, encrypted) == S_OK) { tempDirectory.DisableDeleting(); RefreshListCtrl(); return; } } } } } CRecordVector<UInt32> indices; indices.Add(index); UStringVector messages; bool usePassword = false; UString password; if (_parentFolders.Size() > 0) { const CFolderLink &fl = _parentFolders.Back(); usePassword = fl.UsePassword; password = fl.Password; } HRESULT result = CopyTo(indices, tempDirNorm, false, true, &messages, usePassword, password); if (_parentFolders.Size() > 0) { CFolderLink &fl = _parentFolders.Back(); fl.UsePassword = usePassword; fl.Password = password; } if (!messages.IsEmpty()) return; if (result != S_OK) { if (result != E_ABORT) MessageBoxError(result); return; } if (tryAsArchive) { bool encrypted; if (OpenItemAsArchive(NULL, tempFileInfo, fullVirtPath, encrypted) == S_OK) { tempDirectory.DisableDeleting(); RefreshListCtrl(); return; } } CMyAutoPtr<CTmpProcessInfo> tmpProcessInfoPtr(new CTmpProcessInfo()); CTmpProcessInfo *tmpProcessInfo = tmpProcessInfoPtr.get(); tmpProcessInfo->FolderPath = tempDir; tmpProcessInfo->FilePath = tempFilePath; tmpProcessInfo->NeedDelete = true; tmpProcessInfo->UsePassword = usePassword; tmpProcessInfo->Password = password; if (!tmpProcessInfo->FileInfo.Find(tempFilePath)) return; CTmpProcessInfoRelease tmpProcessInfoRelease(*tmpProcessInfo); if (!tryExternal) return; CProcess process; HRESULT res; if (editMode) res = StartEditApplication(tempFilePath, (HWND)*this, process); else res = StartApplication(tempDirNorm, tempFilePath, (HWND)*this, process); if ((HANDLE)process == 0) return; tmpProcessInfo->Window = (HWND)(*this); tmpProcessInfo->FullPathFolderPrefix = _currentFolderPrefix; tmpProcessInfo->ItemName = name; tmpProcessInfo->ProcessHandle = process.Detach(); NWindows::CThread thread; if (thread.Create(MyThreadFunction, tmpProcessInfo) != S_OK) throw 271824; tempDirectory.DisableDeleting(); tmpProcessInfoPtr.release(); tmpProcessInfoRelease._needDelete = false; }
// metoda pro aktivaci procesu volana pomoci maker // ActivateXXXXX a ReactivateXXXXX // reac == true znamena, ze jde o volani Reactivate // code ucuje typ aktivace // t je cas aktivace // r udava vztazny proces // prior - aktivace pred/po procesu r void CProcess::_activate(bool reac, CODE code, TIME t, CProcess * r, bool prior) { if (this->Terminated()) return; // pokud je proces ukonceny, nelze jej j*z aktivovat if ((this->event != NULL) & !reac) return; // nelze take aktivovat j*z naplanovany proces // nebo pokud nema platny zaznam v SQS CEventNotice* oldEv = this->event; // odkazy na this->event pro reactivate CProcess* oldProc = Current(); switch (code) { case (DIRECT): // Activate() this->event = new CEventNotice(Time(), this); this->event->Rank(true); // vytvor zaznam pro proces // a zarad ho na zacatek SQS break; case (DELAY): t+= Time(); // ActivateDelay(T) // = activate at T+Time() case (AT): // ActivateAt(T) if (t < Time()) t = Time(); // korekce zadaneho casu this->event = new CEventNotice(t, this); this->event->Rank(prior); // vytvoreni a zarazeni udalosti break; case (AFTER): // ActivateAfter case (BEFORE): // ActivateBefore // pokud neexistuje vztazny proces, prip. ten nema // zaznam v SQS, pak ani tento novy proces nebude aktivovan if ((r == NULL) || (r->event == NULL)) this->event = NULL; else { //vytvor polozku eventnotice s casem odpovidajici //casu vztazneho procesu this->event = new CEventNotice(r->event->evTime, this); //zarad ji podle pozadavku <AFTER> <BEFORE> if (code == BEFORE) this->event->Precede(r->event); else this->event->Follow(r->event); } break; default: break; } if (reac) // zruseni stareho zaznamu pro reaktivovany porces if (oldEv != NULL) {oldEv->Out(); delete(oldEv); oldEv=NULL; // if (SQS->Empty()) cout << "CHYBA, prazdna fronta SQS"; // CHYBA! prazdna fronta SQS, nemelo // by nikdy nastat } if (oldProc != NULL) oldProc->ResumeCurrent(); else ResumeCurrent(); // predani rizeni prvnimu naplanovanemu procesu }
void CArchonProcess::CollectGarbage (void) // CollectGarbage // // Collects garbage { CString sTask; try { int i; // Compute how long it's been since we last collected garbage DWORD dwStart = sysGetTickCount(); DWORD dwTimeSinceLastCollection = dwStart - m_dwLastGarbageCollect; // If it has been less than a certain time, then only collect garbage if // all engines are idle. if (dwTimeSinceLastCollection < MAX_GARBAGE_COLLECT_WAIT) { // Check to see if engines are idle bool bEnginesIdle = true; for (i = 0; i < m_Engines.GetCount(); i++) if (!m_Engines[i].pEngine->IsIdle()) { bEnginesIdle = false; break; } // If the engines are busy, then check to see if we have enough // memory to wait some more. if (!bEnginesIdle) { CProcess CurrentProc; CurrentProc.CreateCurrentProcess(); CProcess::SMemoryInfo MemoryInfo; if (!CurrentProc.GetMemoryInfo(&MemoryInfo)) { LogBlackBox(ERR_CANT_GET_MEMORY_INFO); return; } // If we have enough memory, then wait to collect garbage if (MemoryInfo.dwCurrentAlloc < MAX_GARBAGE_COLLECT_MEMORY) return; // Warning that we're running out of memory LogBlackBox(ERR_MEMORY_WARNING); } } // Collect #ifdef DEBUG_GARBAGE_COLLECTION printf("[%s] Collecting garbage.\n", (LPSTR)m_sName); #endif m_dwLastGarbageCollect = dwStart; m_RunEvent.Reset(); m_PauseEvent.Set(); // Keep track of how long each engine takes to pause (for diagnostic // purposes). TArray<DWORD> PauseTime; PauseTime.InsertEmpty(m_Engines.GetCount()); // Some engines still need an explicit call (because they don't have // their own main thread). for (i = 0; i < m_Engines.GetCount(); i++) m_Engines[i].pEngine->SignalPause(); // Wait for the engines to stop for (i = 0; i < m_Engines.GetCount(); i++) { DWORD dwStart = sysGetTickCount(); m_Engines[i].pEngine->WaitForPause(); PauseTime[i] = sysGetTicksElapsed(dwStart); } // Wait for our threads to stop m_EventThread.WaitForPause(); m_ImportThread.WaitForPause(); // Now we ask all engines to mark their data in use for (i = 0; i < m_Engines.GetCount(); i++) { sTask = strPattern("Marking data: %s engine.", m_Engines[i].pEngine->GetName()); m_Engines[i].pEngine->Mark(); } // Now we mark our own structures sTask = STR_MARKING_MNEMOSYNTH; m_MnemosynthDb.Mark(); sTask = STR_MARKING_EVENT_THREAD; m_EventThread.Mark(); sTask = STR_MARKING_IMPORT_THREAD; m_ImportThread.Mark(); // Now we sweep all unused sTask = STR_MARK_AND_SWEEP; DWORD dwSweepStart = sysGetTickCount(); CDatum::MarkAndSweep(); DWORD dwSweepTime = sysGetTickCount() - dwSweepStart; sTask = NULL_STR; // Now we start all engines up again m_PauseEvent.Reset(); m_RunEvent.Set(); // If garbage collection took too long, then we need to log it. DWORD dwTime = sysGetTickCount() - dwStart; if (dwTime >= 500) { // Log each engine that took too long for (i = 0; i < m_Engines.GetCount(); i++) if (PauseTime[i] >= 500) Log(MSG_LOG_INFO, strPattern(STR_ENGINE_PAUSE_TIME, m_Engines[i].pEngine->GetName(), PauseTime[i] / 1000, (PauseTime[i] % 1000) / 10)); // Log overall time Log(MSG_LOG_INFO, strPattern(STR_GARBAGE_COLLECTION, dwTime / 1000, (dwTime % 1000) / 10, dwSweepTime / 1000, (dwSweepTime % 1000) / 10)); } } catch (...) { if (sTask.IsEmpty()) CriticalError(ERR_CRASH_IN_COLLECT_GARBAGE); else CriticalError(strPattern("CRASH: %s", sTask)); } }
WRes MyCreateProcess(LPCWSTR imageName, const UString ¶ms) { CProcess process; return process.Create(imageName, params, 0); }
void CJobObject::Suspend() { CMutex::CEnter MutexEnter(m_Mutex); map<DWORD, int> ErrorProcesses; map<DWORD, int>::iterator ErrorProcess; map<DWORD, BOOL> Processes; map<DWORD, BOOL>::iterator CurrentProcess; map<DWORD, CProcess*>::iterator OldProcess; BOOL bNewProcesses; // Clear all Threads contained in the m_Threads member for (OldProcess = m_Processes.begin(); OldProcess != m_Processes.end(); OldProcess++) { delete OldProcess->second; } m_Processes.clear(); // A) // Seach all threads which belong to this process and suspend them. To do this we create // a snapshot and suspend all threads contained in the snapshot. // Between A1 and A2 it is possible that new threads will be created. This makes it necessary to // create a new snapshot and to suspend all new threads which we not suspended in a previous // iteration. bNewProcesses = TRUE; while (bNewProcesses) { PJOBOBJECT_BASIC_PROCESS_ID_LIST pPidList; bNewProcesses = FALSE; pPidList = CreatePidList(); // A1 if (pPidList == NULL) { throw CCodineException(L"Pid List is NULL", __FILE__, __LINE__); } else { for (int i = 0; i < pPidList->NumberOfProcessIdsInList; i++) { if (m_Processes.find(pPidList->ProcessIdList[i]) == m_Processes.end()) { CProcess *NewProcess = NULL; try { NewProcess = new CProcess(pPidList->ProcessIdList[i]); NewProcess->Suspend(); m_Processes[pPidList->ProcessIdList[i]] = NewProcess; Processes[pPidList->ProcessIdList[i]] = true; bNewProcesses = TRUE; } catch (CCodineException& ex) { ErrorProcess = ErrorProcesses.find(pPidList->ProcessIdList[i]); if (ErrorProcess == ErrorProcesses.end() || (ErrorProcess != ErrorProcesses.end() && ErrorProcess->second < 3)) { // Possible reasons for the exception // * We didn't get a handle // - Thread exited // * Thread belongs to a different process // (no access) // - Thread exited and another process created // a thread with the same id between A1 and A2 // // => we try it once more -> the next snapshot won't // contain the current thread CTrace::Print(CTrace::Layer::TEST, L"Catched Exception during suspended" L" for thread %ld", pPidList->ProcessIdList[i]); ErrorProcesses[pPidList->ProcessIdList[i]]++; bNewProcesses = TRUE; } else { // If we get an error three times for the same thread // then we will assume that this thread belongs really // to this process // // => we could not solve the problem => ERROR throw ex; } } } } // A2 } DestroyPidList(); } // B // Between A and B we created a map of suspended threads (Threads) // but we can not be sure that all these threads belong to this process // (=> recycling of thread id's). It is possible, that we suspended // threads of foreign processes!. Now we will set pair.second to false // for all threads which belong to the current process { PJOBOBJECT_BASIC_PROCESS_ID_LIST pPidList; int i; pPidList = CreatePidList(); if (pPidList == NULL) { throw CCodineException(L"Pid List is NULL", __FILE__, __LINE__); } else { try { for (i = 0; i < pPidList->NumberOfProcessIdsInList; i++) { CurrentProcess = Processes.find(pPidList->ProcessIdList[i]); if (CurrentProcess == Processes.end()) { // If we get a new thread id here, then someone else // created a new thread for this process (CreateRemoteThread()) CTrace::Print(CTrace::Layer::TEST, L"Unexpected new thread %ld", pPidList->ProcessIdList[i]); throw CCodineException(L"", __FILE__, __LINE__); } else { CurrentProcess->second = FALSE; } } } catch (CCodineException& ex) { map<DWORD, CProcess*>::iterator TheProcess; // If we come here then we will rollback previous activities // Therefore we have to resume all threads contained in Threads for (TheProcess = m_Processes.begin(); TheProcess != m_Processes.end(); TheProcess++) { try { (*TheProcess).second->Resume(); } catch (CCodineException&) { ; } } throw ex; } } DestroyPidList(); } // C // Between B and C we set pair.second to false for all threads // which belong to the current process // Now we have to resume the remaining threads // We will also add the suspended threads of this process to // the member m_Threads. try { // Resume and copy for (CurrentProcess = Processes.begin(); CurrentProcess != Processes.end(); CurrentProcess++) { if (CurrentProcess->second == TRUE) { CProcess *ForeignProcess = m_Processes[CurrentProcess->first]; ForeignProcess->Resume(); m_Processes.erase(CurrentProcess->first); CTrace::Print(CTrace::Layer::TEST, L"Resumed foreign thread %ld", CurrentProcess->first); break; } } } catch (CCodineException& ex) { // What can we do here? throw ex; } }
void CAlgorithmRoundRobin::Run(CNode *io_node) { CProcess* pProcess = NULL; bool nop = false; if (io_node->GetProcessCount() == 0) nop = true; else pProcess = io_node->GetProcess(io_node->GetRunningProcessIndex()); // This is simulating the tick // Step 1 : we want to print: run %crtTime% %pid% %programCounter% %isMemAcess% // Step 2 : and make the page dirty if that's the case. // Step 3 : Decrement the round-robin tick counter and see if we need to change the process // We don't need to be concerned about incrementing the time since that is the node's job // Step 1: // crtTime = io_node->GetCurrentTimeTemp(); // pid = pProcess->GetId() // programPointer = pProcess->GetProgramPointer() // isMemAcess = pProcess->IsNextCommandMemAccess(); if (!nop && pProcess->IsRunning()) { if (pProcess->GetProgramPointer() == 0) io_node->WriteLog(boost::str(boost::format("LOOP START CrtTime: %f \tPID: %d \t") % io_node->GetCurrentTimeTemp() % pProcess->GetId())); //io_node->m_tempStringStream << "RUN CrtTime:" << io_node->GetCurrentTimeTemp() << "\tPID:" << pProcess->GetId() << "\tProgramPointer:" << pProcess->GetProgramPointer() << "\tIsMemAccess:" << pProcess->IsCurrentCommandMemAccess() << std::endl; io_node->WriteLog(boost::str(boost::format("RUN CrtTime: %f \tPID: %d \tProgramPointer: %d \tIsMemAccess: %d") % io_node->GetCurrentTimeTemp() % pProcess->GetId() % pProcess->GetProgramPointer() % pProcess->IsCurrentCommandMemAccess())); io_node->IncrementProcTicks(); // Step 2: if (pProcess->IsCurrentCommandMemAccess()) pProcess->MarkPageAsDirty(io_node->GetPageSize()); pProcess->IncrementProgramPointer(); // if this was the last command, we want to do some things if (pProcess->GetProgramPointer() == 0) { io_node->WriteLog(boost::str(boost::format("LOOP END CrtTime: %f \tPID: %d \t") % io_node->GetCurrentTimeTemp() % pProcess->GetId())); // The process reached the deadline and will start next time it's required pProcess->SetRunState(false); // set the process to wake up after the initial deadline passed if (pProcess->GetMarkedDeadlineMissed()) // if the deadline was missed, we'll set a new deadline based on the time that the process failed // this can help when there are multiple processes missing the deadline and moving just one would save // the day for multiple processes pProcess->SetWakeUpTime(io_node->GetCurrentTimeTemp()); else pProcess->SetWakeUpTime(pProcess->GetWakeUpTime() + pProcess->GetDeadline()); //pProcess->SetLastDeadlineTick(pProcess->GetLastDeadlineTick() + pProcess->GetDeadline()); pProcess->SetMarkedDeadlineMissed(false); } // Check for a migration on every tick if (io_node->GetCurrentTimeTemp() > pProcess->GetWakeUpTime() + pProcess->GetDeadline() && !pProcess->GetMarkedDeadlineMissed()) { // If we are here, the process missed the deadline. We should report it io_node->WriteLog(boost::str(boost::format("DEADLINE MISSED CrtTime: %f \tDeadline time: %f \tPID: %d") % io_node->GetCurrentTimeTemp() % (pProcess->GetWakeUpTime() + pProcess->GetDeadline()) % pProcess->GetId())); // We are going to migrate only if the migration is enabled and the current process is not scheduled for migration pProcess->SetMarkedDeadlineMissed(true); // We migrate if the migration is enabled and we haven't already started a migration on this node. if (CMasterSingleton::GetInstance()->IsMigrationEnabled() && !io_node->IsAlarmUp()) { // Schedule the migration here CMigrationInfo* pMigrationInfo = new CMigrationInfo(); // decide which one is the destination node by getting the one with the free-est processor CNode* destinationNode = pMigrationInfo->FindNodeWithFreeCpu(io_node, pProcess); if (destinationNode) { if (!pMigrationInfo->ScheduleMigration(io_node, destinationNode, pProcess)) // delete the object if the schedule failed to avoid memory leaks delete pMigrationInfo; } else { io_node->WriteLog("Failed to find destination node for migration!"); } } } } else { //io_node->m_tempStringStream << "NOP CrtTime:" << io_node->GetCurrentTimeTemp() << std::endl; io_node->WriteLog(boost::str(boost::format("NOP CrtTime: %f") % io_node->GetCurrentTimeTemp())); io_node->IncrementNopTicks(); } // Step 3: --m_ticksLeft; if (m_ticksLeft == 0) { m_ticksLeft = m_ticksPerProcess; io_node->m_tempStringStream << "RR CYCLE END" << std::endl; // After each RR cycle is done, get through all the processes and check if we should update the running state. for (uint32_t i = 0; i < io_node->GetProcessCount(); ++i) { CheckIfProcessCanRun(io_node, io_node->GetProcess(i)); } //Afterwards, find the next process that we can run.If none available, just wait. GetNextRunningProcess(io_node); } }