/** * The actual function that adds messages. Does NOT send an ack. * The msgIndex specifies the index on which to place this message. If the * value is zero it does an automatic placement. * Returns zero on failure. */ const Msg* Shell::innerAddMsg( string msgType, ObjId src, string srcField, ObjId dest, string destField, unsigned int msgIndex ) { /* cout << myNode_ << ", Shell::handleAddMsg: " << msgType << ", " << mid << ", src =" << src << "." << srcField << ", dest =" << dest << "." << destField << "\n"; */ const Finfo* f1 = src.id.element()->cinfo()->findFinfo( srcField ); if ( f1 == 0 ) return 0; const Finfo* f2 = dest.id.element()->cinfo()->findFinfo( destField ); if ( f2 == 0 ) return 0; // Should have been done before msgs request went out. assert( f1->checkTarget( f2 ) ); Msg *m = 0; if ( msgType == "diagonal" || msgType == "Diagonal" ) { m = new DiagonalMsg( src.id.element(), dest.id.element(), msgIndex ); } else if ( msgType == "sparse" || msgType == "Sparse" ) { m = new SparseMsg( src.id.element(), dest.id.element(), msgIndex ); } else if ( msgType == "Single" || msgType == "single" ) { m = new SingleMsg( src.eref(), dest.eref(), msgIndex ); } else if ( msgType == "OneToAll" || msgType == "oneToAll" ) { m = new OneToAllMsg( src.eref(), dest.id.element(), msgIndex ); } else if ( msgType == "AllToOne" || msgType == "allToOne" ) { m = new OneToAllMsg( dest.eref(), src.id.element(), msgIndex ); // Little hack. } else if ( msgType == "OneToOne" || msgType == "oneToOne" ) { m = new OneToOneMsg( src.eref(), dest.eref(), msgIndex ); } else { cout << myNode_ << ": Error: Shell::handleAddMsg: msgType not known: " << msgType << endl; return m; } if ( m ) { if ( f1->addMsg( f2, m->mid(), src.id.element() ) ) { return m; } delete m; m = 0; } cout << myNode_ << ": Error: Shell::handleAddMsg: Unable to make/connect Msg: " << msgType << " from " << src.id.element()->getName() << " to " << dest.id.element()->getName() << endl; return m; }
static bool addClockMsg( unsigned int tick, Id tgt, const Finfo* f2 ) { Id clockId( 1 ); stringstream ss; ss << "proc" << tick; const Finfo* f1 = clockId.element()->cinfo()->findFinfo( ss.str() ); assert( f1 ); assert( f2 ); Msg* m = new OneToAllMsg( clockId.eref(), tgt.element(), 0 ); if ( m ) { if ( f1->addMsg( f2, m->mid(), clockId.element() ) ) { return true; } delete m; } cout << "Error: Element::setTick: failed to connect " << tgt << " to clock\n"; return false; }
bool Shell::innerMove( Id orig, ObjId newParent ) { static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" ); static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf ); static const FuncId pafid = pf2->getFid(); static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" ); assert( !( orig == Id() ) ); assert( !( newParent.element() == 0 ) ); ObjId mid = orig.element()->findCaller( pafid ); Msg::deleteMsg( mid ); Msg* m = new OneToAllMsg( newParent.eref(), orig.element(), 0 ); assert( m ); if ( !f1->addMsg( pf, m->mid(), newParent.element() ) ) { cout << "move: Error: unable to add parent->child msg from " << newParent.element()->getName() << " to " << orig.element()->getName() << "\n"; return 0; } return 1; }
/** * Static utility function. Attaches child element to parent element. * Must only be called from functions executing in parallel on all nodes, * as it does a local message addition * MsgIndex is needed to be sure that the same msg identifies parent-child * connection on all nodes. */ bool Shell::adopt( ObjId parent, Id child, unsigned int msgIndex ) { static const Finfo* pf = Neutral::initCinfo()->findFinfo( "parentMsg" ); // static const DestFinfo* pf2 = dynamic_cast< const DestFinfo* >( pf ); // static const FuncId pafid = pf2->getFid(); static const Finfo* f1 = Neutral::initCinfo()->findFinfo( "childOut" ); assert( !( child.element() == 0 ) ); assert( !( child == Id() ) ); assert( !( parent.element() == 0 ) ); Msg* m = new OneToAllMsg( parent.eref(), child.element(), msgIndex ); assert( m ); // cout << myNode_ << ", Shell::adopt: mid = " << m->mid() << ", pa =" << parent << "." << parent()->getName() << ", kid=" << child << "." << child()->getName() << "\n"; if ( !f1->addMsg( pf, m->mid(), parent.element() ) ) { cout << "move: Error: unable to add parent->child msg from " << parent.element()->getName() << " to " << child.element()->getName() << "\n"; return 0; } return 1; }