coriolis/crlcore/src/ccore/ToolEngine.cpp

400 lines
12 KiB
C++

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./ToolEngine.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Commons.h"
#include "hurricane/Error.h"
#include "hurricane/Cell.h"
#include "hurricane/Relation.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolEngine.h"
namespace {
using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::ostringstream;
using std::set;
using std::vector;
using Hurricane::ForEachIterator;
using Hurricane::_TName;
using Hurricane::Error;
using Hurricane::Name;
using Hurricane::Relation;
using Hurricane::Record;
using Hurricane::Cell;
using CRL::ToolEngine;
const Name ToolEnginesRelationName = "ToolEnginesRelationName";
// -------------------------------------------------------------------
// Class : "CRL::ToolEnginesRelation".
class ToolEnginesRelation : public Relation {
public:
// Static Methods.
static ToolEnginesRelation* getToolEnginesRelation ( const Cell* cell );
static void destroyAllToolEnginesRelations ();
// Constructor.
static ToolEnginesRelation* create ( Cell* masterOwner );
// Methods.
virtual Name getName () const;
inline unsigned int getPlacementModificationFlag () const;
inline unsigned int updatePlacementModificationFlag ();
inline unsigned int getRoutingModificationFlag () const;
inline unsigned int updateRoutingModificationFlag ();
virtual string _getTypeName () const;
virtual Record* _getRecord () const;
private:
// Internal: Constructor.
ToolEnginesRelation ( Cell* masterOwner );
protected:
virtual void _preDestroy ();
private:
// Internal: Attributes
static set<ToolEnginesRelation*> _toolEnginesRelations;
unsigned int _placementModificationFlag;
unsigned int _routingModificationFlag;
};
set<ToolEnginesRelation*> ToolEnginesRelation::_toolEnginesRelations;
ToolEnginesRelation::ToolEnginesRelation ( Cell* masterOwner )
: Relation (masterOwner)
, _placementModificationFlag(0)
, _routingModificationFlag (0)
{ }
ToolEnginesRelation* ToolEnginesRelation::create ( Cell* masterOwner )
{
ToolEnginesRelation* enginesRelation = new ToolEnginesRelation(masterOwner);
enginesRelation->_postCreate();
_toolEnginesRelations.insert ( enginesRelation );
return enginesRelation;
}
void ToolEnginesRelation::_preDestroy ()
{
ToolEngine* tool;
while ( (tool = getSlaveOwners().getSubSet<ToolEngine*>().getFirst()) ) {
tool->setInRelationDestroy( true );
tool->destroy();
}
Relation::_preDestroy();
}
Name ToolEnginesRelation::getName () const
{ return ToolEnginesRelationName; }
inline unsigned int ToolEnginesRelation::getPlacementModificationFlag () const
{ return _placementModificationFlag; }
inline unsigned int ToolEnginesRelation::getRoutingModificationFlag () const
{ return _routingModificationFlag; }
inline unsigned int ToolEnginesRelation::updatePlacementModificationFlag ()
{ return ++_placementModificationFlag; }
inline unsigned int ToolEnginesRelation::updateRoutingModificationFlag ()
{ return ++_routingModificationFlag; }
string ToolEnginesRelation::_getTypeName () const
{ return _TName ( "ToolEnginesRelation" ); }
Record* ToolEnginesRelation::_getRecord () const
{
Record* record = Relation::_getRecord();
if ( record ) {
record->add ( getSlot ( "placementModificationFlag", &_placementModificationFlag ) );
record->add ( getSlot ( "routingModificationFlag" , &_routingModificationFlag ) );
}
return record;
}
ToolEnginesRelation* ToolEnginesRelation::getToolEnginesRelation ( const Cell* cell )
{
if ( !cell )
throw Error ( "Can't get " + _TName("ToolEnginesRelation") + " : empty cell" );
Property* property = cell->getProperty(ToolEnginesRelationName);
if ( !property )
return NULL;
else {
ToolEnginesRelation* enginesRelation = dynamic_cast<ToolEnginesRelation*>(property);
if ( !enginesRelation )
throw Error ( "Bad Property type: Must be a ToolEnginesRelation" );
return enginesRelation;
}
}
void ToolEnginesRelation::destroyAllToolEnginesRelations ()
{
set<ToolEnginesRelation*>::iterator irelation = _toolEnginesRelations.begin();
for ( ; irelation != _toolEnginesRelations.end() ; ++irelation ) {
vector<ToolEngine*> tools;
forEach ( ToolEngine*, itool, (*irelation)->getSlaveOwners().getSubSet<ToolEngine*>() ) {
tools.push_back( *itool );
}
for ( size_t i=0 ; i<tools.size() ; ++i )
tools[i]->destroy();
}
_toolEnginesRelations.clear();
}
} // End of anonymous namespace.
namespace CRL {
// -------------------------------------------------------------------
// Class : "CRL::ToolEngine".
bool ToolEngine::_inDestroyAll = false;
ToolEngine::ToolEngine ( Cell* cell )
: Super()
, _cell (cell)
, _placementModificationFlag(0)
, _routingModificationFlag (0)
, _inRelationDestroy (false)
, _timer ()
, _passNumber (0)
{ }
void ToolEngine::_postCreate ()
{
Super::_postCreate();
if (not _cell)
throw Error( "Can't create " + _TName("ToolEngine") + " : empty _cell" );
ToolEnginesRelation* enginesRelation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if (not enginesRelation)
enginesRelation = ToolEnginesRelation::create( _cell );
else
for ( ToolEngine* tool : enginesRelation->getSlaveOwners().getSubSet<ToolEngine*>() ) {
if (tool->getName() == getName())
throw Error( "Can't create " + _TName("ToolEngine") + " : already exists !!" );
}
put( enginesRelation );
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
<< _cell->getName() << ">" << endl;
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
}
void ToolEngine::_preDestroy ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation( _cell );
if (not _inRelationDestroy) {
if (not relation)
throw Error( "Abnormal state: no ToolEnginesRelation on %s", getString(_cell).c_str() );
remove( relation );
}
Super::_preDestroy();
_cell->notify( Cell::Flags::CellChanged );
}
bool ToolEngine::inDestroyAll ()
{ return _inDestroyAll; }
void ToolEngine::destroyAll ()
{
_inDestroyAll = true;
ToolEnginesRelation::destroyAllToolEnginesRelations();
_inDestroyAll = false;
}
string ToolEngine::_getTypeName () const
{ return _TName ( "ToolEngine" ); }
string ToolEngine::_getString () const
{
string s = Super::_getString();
s.insert(s.length() - 1, " " + getString(_cell->getName()));
return s;
}
Record* ToolEngine::_getRecord () const
{
Record* record = Super::_getRecord();
if ( record ) {
record->add ( getSlot ( "Cell" , _cell ) );
record->add ( getSlot ( "Name" , getName() ) );
record->add ( getSlot ( "placementModificationFlag", _placementModificationFlag ) );
record->add ( getSlot ( "routingModificationFlag" , _routingModificationFlag ) );
}
return record;
}
void ToolEngine::grabPlacementModificationFlag ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
_placementModificationFlag = relation->updatePlacementModificationFlag();
}
void ToolEngine::getPlacementModificationFlag ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
_placementModificationFlag = relation->getPlacementModificationFlag();
}
bool ToolEngine::placementModificationFlagHasChanged ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
return ( _placementModificationFlag != relation->getPlacementModificationFlag() );
}
void ToolEngine::grabRoutingModificationFlag ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
_routingModificationFlag = relation->updateRoutingModificationFlag ();
}
void ToolEngine::getRoutingModificationFlag ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
_routingModificationFlag = relation->getRoutingModificationFlag ();
}
bool ToolEngine::routingModificationFlagHasChanged ()
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(_cell);
if ( !relation )
throw Error ( "Abnormal state: no ToolEnginesRelation on cell ..." );
return ( _routingModificationFlag != relation->getRoutingModificationFlag() );
}
ToolEngines ToolEngine::get ( const Cell* cell )
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(cell);
if ( relation )
return relation->getSlaveOwners().getSubSet<ToolEngine*>();
else
return ToolEngines();
}
ToolEngine* ToolEngine::get ( const Cell* cell, const Name& name )
{
ToolEnginesRelation* relation = ToolEnginesRelation::getToolEnginesRelation(cell);
if (not relation) {
return NULL;
} else {
forEach ( ToolEngine*, itool, relation->getSlaveOwners().getSubSet<ToolEngine*>()) {
if (itool->getName() == name)
return *itool;
}
return NULL;
}
}
void ToolEngine::startMeasures ()
{
_timer.resetIncrease();
_timer.start();
}
void ToolEngine::stopMeasures ()
{ _timer.stop(); }
void ToolEngine::suspendMeasures ()
{ _timer.suspend(); }
void ToolEngine::resumeMeasures ()
{ _timer.resume(); }
void ToolEngine::printMeasures () const
{
ostringstream result;
result << Timer::getStringTime(_timer.getCombTime())
<< ", " << Timer::getStringMemory(_timer.getIncrease());
cmess1 << Dots::asString( " - Done in", result.str() ) << endl;
result.str("");
result << _timer.getCombTime()
<< "s, +" << (_timer.getIncrease()>>10) << "Kb/"
<< Timer::getStringMemory(Timer::getMemorySize());
cmess2 << Dots::asString( " - Raw measurements", result.str() ) << endl;
// result.str("");
// result << Timer::getStringMemory(Timer::getMemorySize());
// cmess1 << Dots::asString( " - Total memory", result.str() ) << endl;
}
} // End of CRL namespace.