// Derived classes use this method to seed the initial set of jobs. // Will be called by 'KKJobManager' at appropriate time. KKJobListPtr RandomSplitJobManager::JobsCreateInitialSet () { KKJobListPtr initialJobs = new KKJobList (this); for (int splitNum = 0; splitNum < numSplits; splitNum++) { RandomSplitJobPtr j = new RandomSplitJob (this, GetNextJobId (), -1, splitNum, log); initialJobs->PushOnBack (j); } return initialJobs; } /* JobsCreateInitialSet */
void KKJobManager::ProcessNextExpansion (ostream& o) { KKJobListPtr jobsJustCompleted = new KKJobList (this); jobsJustCompleted->Owner (false); { // Add jobs completed since last expansion to this list. KKJobList::iterator idx; for (idx = jobs->begin (); idx != jobs->end (); idx++) { KKJobPtr j = *idx; if (j->JobId () >= expansionFirstJobId) jobsJustCompleted->PushOnBack (j); } } // Derived class will now peform expansion. KKJobListPtr expandedJobs = JobsExpandNextSetOfJobs (jobsJustCompleted); { if (expandedJobs) { expandedJobs->Owner (false); KKJobList::iterator idx; for (idx = expandedJobs->begin (); idx != expandedJobs->end (); idx++) { KKJobPtr j = *idx; if (j->JobId () < expansionFirstJobId) expansionFirstJobId = j->JobId (); jobs->PushOnBack (j); o << "KKJob" << "\t" << j->JobType () << "\t" << j->ToStatusStr () << endl; } } delete expandedJobs; expandedJobs = NULL; } delete jobsJustCompleted; jobsJustCompleted = NULL; o << "NextJobId" << "\t" << nextJobId << endl << "ExpansionCount" << "\t" << expansionCount << endl << "ExpansionFirstJobId" << "\t" << expansionFirstJobId << endl; } /* ProcessNextExpansion */
void KKJobManager::Run () { log.Level (10) << "KKJobManager::Run." << endl; bool keepOnRunning = true; KKJobListPtr executedJobs = NULL; KKJobListPtr jobsToExecute = GetNextSetOfJobs (NULL); while (keepOnRunning && (!quitRunning)) { if (jobsToExecute) { delete executedJobs; executedJobs = NULL; executedJobs = new KKJobList (this); executedJobs->Owner (true); KKJobList::iterator idx; for (idx = jobsToExecute->begin (); idx != jobsToExecute->end (); idx++) { KKJobPtr j = *idx; j->ProcessNode (); executedJobs->PushOnBack (j->Duplicate ()); } delete jobsToExecute; jobsToExecute = NULL; } else { if (!(jobs->JobsStillRunning ())) { keepOnRunning = false; } else { // We will sleep for a bit until there are more jobs to run log.Level (10) << "KKJobManager::Run No jobs avaialble to run; will sleep a bit." << endl; osSleep ((float)(30 + rand () % 10)); } } if (keepOnRunning) jobsToExecute = GetNextSetOfJobs (executedJobs); delete executedJobs; executedJobs = NULL; } Block (); StatusFileRefresh (); if ((!quitRunning) && (status != KKJob::jsDone)) { if (status != KKJob::jsDone) { GenerateFinalResultsReport (); status = KKJob::jsDone; ofstream* statusFile = StatusFileOpen (ios::app); *statusFile << "Status" << "\t" << StatusStr () << endl; ReportCpuTimeUsed (statusFile); statusFile->close (); delete statusFile; } } EndBlock (); log.Level (10) << "KKJobManager::Run Exiting." << endl; } /* Run */
KKJobListPtr KKJobManager::GetNextSetOfJobs (KKJobListPtr completedJobs) { log.Level (20) << "KKJobManager::GetNextSetOfJobs." << endl; Block (); StatusFileRefresh (); if (completedJobs) { // We will first write out results of jobs that have been completed, ofstream* statusFile = StatusFileOpen (ios::app); KKJobList::iterator idx; for (idx = completedJobs->begin (); idx != completedJobs->end (); idx++) { KKJobPtr j = *idx; *statusFile << "KKJob" << "\t" << j->JobType () << "\t" << j->ToStatusStr () << endl; if (supportCompletedJobData) { *statusFile << "<KKJob JobType=" << j->JobType () << ", " << "JobId=" << j->JobId () << ">" << endl; j->CompletedJobDataWrite (*statusFile); *statusFile << "</job>" << endl; } KKJobPtr existingJob = jobs->LookUpByJobId (j->JobId ()); if (existingJob) { existingJob->ReFresh (*j); } else { log.Level (-1) << endl << endl << endl << "GetNextSetOfJobs *** ERROR ***" << endl << endl << " Could not locate KKJob[" << j->JobId () << "]" << endl << endl; return NULL; } } statusFile->close (); delete statusFile; statusFile = NULL; } KKJobListPtr jobsToExecute = new KKJobList (this); jobsToExecute->Owner (false); if (!quitRunning) { ofstream* statusFile = StatusFileOpen (ios::app); KKJobPtr nextJob = jobs->LocateOpenJob (); if (!nextJob) { if (jobs->AreAllJobsDone ()) { // There are no jobs to do; we will have to expand some existing jobs then ProcessNextExpansion (*statusFile); nextJob = jobs->LocateOpenJob (); } else { // There are still some jobs that are running. We are going to go to // for now and try again later. // // By leaving "nextJob = NULL" we will drop strait through the rest of // this method and return to the caller with 'jobsToExecute' empty // signaling that it will need to sleep for a while before calling // us again. } } while (nextJob && (jobsToExecute->QueueSize () < numJobsAtATime)) { jobsToExecute->PushOnBack (nextJob); nextJob->Status (jsStarted); *statusFile << "JobStatusChange" << "\t" << nextJob->JobId () << "\t" << nextJob->StatusStr () << endl; nextJob = jobs->LocateOpenJob (); } statusFile->close (); } if (jobsToExecute->QueueSize () < 1) { delete jobsToExecute; jobsToExecute = NULL; } EndBlock (); log.Level (20) << "KKJobManager::GetNextSetOfJobs Exiting." << endl; return jobsToExecute; } /* GetNextSetOfJobs */