void CRUTopologicalDGIterator::Build()
{
	TaskLink link;

	// Fill the data structures by references to available tasks
	DSListPosition pos = GetAllTasksList().GetHeadPosition();
	while (NULL != pos)
	{
		CRUTask *pTask = GetAllTasksList().GetNext(pos);
		link.pTask_ = pTask;

		// The tasks that need to be traversed before me
		CRUTaskList &refTaskList =
			(DIRECT == dir_) ? 
				pTask->GetTasksThatIDependOn() :
				pTask->GetTasksThatDependOnMe();
			
		link.refCount_ = refTaskList.GetCount();
		
		// Place the link into the hash
		allTasksLinkMap_[pTask->GetId()] = link;

		// If this is a ready task, 
		// place a reference to it into the ready list
		if (0 == link.refCount_)
		{
			readyTasksList_.AddHead(link.pTask_);
		}
	}

	// My guess is that this is a circular graph
	RUASSERT(FALSE == readyTasksList_.IsEmpty()); 

	SetCurrentTask(readyTasksList_.RemoveHead());
}
void CRUTopologicalDGIterator::Next()
{
	RUASSERT(FALSE == allTasksLinkMap_.IsEmpty());

	CRUTask *pTask = GetCurrentTask();
	if (NULL == pTask)
	{
		return; // all the tasks have been already traversed
	}

	// The tasks that need to be traversed after me
	CRUTaskList &refTaskList = 
		(DIRECT == dir_) ? 
			pTask->GetTasksThatDependOnMe() :
			pTask->GetTasksThatIDependOn();

	// For all of these tasks, decrecase the reference count
	// Update the "ready" list, if any of the tasks have become ready.
	UpdateIterator(refTaskList);

	// Select a new current task
	if (TRUE == readyTasksList_.IsEmpty())
	{
		SetCurrentTask(NULL); // The last task has just been traversed
	}
	else
	{
		// Retrieve a new task from the "ready" list
		SetCurrentTask(readyTasksList_.RemoveHead());
	}
}
void CRUTopologicalDGIterator::UpdateIterator(CRUTaskList &taskList)
{
	TaskLink link = {NULL, 0};

	DSListPosition pos = taskList.GetHeadPosition();
	while (NULL != pos)
	{
		CRUTask *pTask = taskList.GetNext(pos);

		// Locate the link in the link map
		BOOL ret = allTasksLinkMap_.Lookup(pTask->GetId(), link);
		RUASSERT(TRUE == ret);

		// One reference less to the task
		link.refCount_--;

		if (0 == link.refCount_)
		{
			// One more task has no dependencies, place it to the ready list
			readyTasksList_.AddHead(link.pTask_);
		}
		else 
		{
			// Update the link's reference count in the hash
			allTasksLinkMap_[pTask->GetId()] = link;
		}
	}
}
void CRUDependenceGraph::DumpGraph(CDSString &to)
{
	to += "\n\t\tDEPENDENCE GRAPH DRAWING START\n";

	to += "digraph G { \n\n";

	to += " graph [	fontname = \"Helvetica-Oblique\",page = \"8,10\", margin = \"1.5,1.5\"];\n\n";
	to += "node [style=filled,fontsize=14];\n\n";

	CRUTask *pTask;
	CRUTopologicalDGIterator firstPass(*this, CRUTopologicalDGIterator::DIRECT);

	for (; (pTask = firstPass.GetCurrentTask()) != NULL; firstPass.Next())
	{
		pTask->DumpGraphNode(to);
	}
	
	CRUTopologicalDGIterator secondPass(*this, CRUTopologicalDGIterator::DIRECT);

	for (; (pTask = secondPass.GetCurrentTask()) != NULL; secondPass.Next())
	{
		pTask->DumpGraphEdges(to);
	}

	to += "\n}\n\n\t\tDEPENDENCE GRAPH DRAWING END\n";
}
예제 #5
0
//--------------------------------------------------------------------------//
//	CRUTask::Dump()
//
//	Called by CRUDependenceGraph::Dump()
//
//	Prints the "standard" task's dump
//--------------------------------------------------------------------------//
// LCOV_EXCL_START :dpm
void CRUTask::Dump(CDSString &to)
{
    char idStr[10];
    sprintf(idStr,"%d",GetId());

    to += "\nTASK ID = " + CDSString(idStr);
    to += "\n\t" + GetTaskName() + "\n";

    if (0 == pSuccList_->GetCount())
    {
        to += "\tNo tasks depend on me.\n";
    }
    else
    {
        to += "\tTasks that depend on me:\n";

        DSListPosition pos = pSuccList_->GetHeadPosition();
        while (NULL != pos)
        {
            CRUTask *pTask = pSuccList_->GetNext(pos);
            sprintf(idStr,"%d",pTask->GetId());
            to += "\t\tTask id = " + CDSString(idStr) + "\n";
        }
    }
}
void CRUDependenceGraph::ComputeGainFunction()
{
	CRUTask *pTask;

	CRUTopologicalDGIterator it(*this, CRUTopologicalDGIterator::REVERSE);
	for (; (pTask = it.GetCurrentTask()) != NULL; it.Next())
	{
		pTask->ComputeGain();
	}
}
void CRUDependenceGraph::Dump(CDSString &to)
{
	to += "\n\t\tDEPENDENCE GRAPH DUMP\n";

	CRUTask *pTask;
	CRUTopologicalDGIterator it(*this, CRUTopologicalDGIterator::DIRECT);

	for (; (pTask = it.GetCurrentTask()) != NULL; it.Next())
	{
		pTask->Dump(to);
	}
}
예제 #8
0
void CRUTask::RemoveAllTasksThatIDependOn()
{
    DSListPosition pos = GetTasksThatIDependOn().GetHeadPosition();

    while (NULL != pos)
    {
        CRUTask *pFromTask = GetTasksThatIDependOn().GetNext(pos);
        pFromTask->GetTasksThatDependOnMe().RemoveRefToTask(this);
    }

    GetTasksThatIDependOn().RemoveAll();
}
void CRUDependenceGraph::ScheduleDoomedTask()
{
	CRUTask *pTask;
	CRUTopologicalDGIterator it(*this, CRUTopologicalDGIterator::DIRECT);

	for (; (pTask = it.GetCurrentTask()) != NULL; it.Next())
	{
		if (0 != pTask->GetStatus())
		{
			pScheduledTask_ = pTask;
			return;
		}
	}
}
BOOL CRUDependenceGraph::AllEmpCheckTasksComplete() const
{
        DSListPosition pos = availableTaskList_.GetHeadPosition();

	while (NULL != pos) 
	{
		CRUTask *pTask = availableTaskList_.GetNext(pos);

                if( CRUTask::EMP_CHECK == pTask->GetType() )
                {
                  return FALSE;
                }
        }
        return TRUE;
}
예제 #11
0
CRUTask *CRUTaskList::FindTask(Lng32 taskId)
{
    DSListPosition pos = GetHeadPosition();

    while (NULL != pos)
    {
        CRUTask *pTask = GetNext(pos);
        if (pTask->GetId() == taskId)
        {
            return pTask;
        }
    }

    return NULL;
}
예제 #12
0
void CRUTask::HandlePredecessorFailure(CRUTask &task)
{
    RUASSERT (0 != task.GetStatus());

    // If there is already something wrong, don't touch me
    if (0 != this->GetStatus())
    {
        return;
    }

    // The error's text will be printed only for the Refresh tasks.
    CRUException &ex = GetErrorDesc();
    ex.SetError(IDS_RU_TASK_PREDECESSOR_PROBLEM);
    ex.AddArgument(this->GetTaskName());
    ex.AddArgument(task.GetTaskName());
}
CRUTask *CRUDependenceGraph::GetTask(TInt64 objUid, CRUTask::Type type)
{
	DSListPosition pos = availableTaskList_.GetHeadPosition();

	while (NULL != pos) 
	{
		CRUTask *pTask = availableTaskList_.GetNext(pos);
	
		if (TRUE == pTask->HasObject(objUid) 
			&&
			type == pTask->GetType()
			)
		{
			return pTask;
		}
	}

	return NULL;
}
예제 #14
0
//--------------------------------------------------------------------------//
//	CRUTask::DumpGraphNode()
//
//	Called by CRUDependenceGraph::DumpGraph()
//
//	Prints the task's edges dump acceptable for the Dotty GUI
//
//--------------------------------------------------------------------------//
// LCOV_EXCL_START :dpm
void CRUTask::DumpGraphEdges(CDSString &to)
{
    if (0 == pSuccList_->GetCount())
    {
        return;
    }

    char fromChr[10],toChr[10];
    sprintf(fromChr,"%d",GetId());

    CDSString fromStr(fromChr);
    fromStr = "\t\t" + fromStr + " -> ";

    DSListPosition pos = pSuccList_->GetHeadPosition();
    while (NULL != pos)
    {
        CRUTask *pTask = pSuccList_->GetNext(pos);
        sprintf(toChr,"%d",pTask->GetId());
        to += fromStr + CDSString(toChr) + ";\n";
    }
}
예제 #15
0
void CRUTask::ComputeGain()
{
    TInt32 gain=0, maxGain=0;

    // First, update the (local) cost estimate
    ComputeCost();

    // Next, update the (global) gain estimate
    DSListPosition pos = pSuccList_->GetHeadPosition();

    // Compute the maximum gain between successor tasks
    while (NULL != pos)
    {
        CRUTask *pSuccTask = pSuccList_->GetNext(pos);
        gain = pSuccTask->GetGain();

        maxGain = (gain > maxGain) ? gain : maxGain;
    }

    // Update the gain
    gain_ = GetCost() + maxGain;
}
void CRUDependenceGraph::ScheduleNormalTask()
{
	ComputeGainFunction();

	CRUTopologicalDGIterator it(*this, CRUTopologicalDGIterator::DIRECT);
	CRUTask *pTask;

	for (; (pTask = it.GetCurrentTask()) != NULL; it.Next())
	{
		RUASSERT (0 == pTask->GetStatus());

		// Consider only ready tasks that are not being executed already
		if (FALSE == pTask->IsReady()
			||
			TRUE == pTask->IsRunning())
		{
			continue;
		}
		
		// Examine the task's candidateship ...
		ConsiderTaskForScheduling(pTask);
	}
}