• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

sst/elements/include/eventChannel2.h

00001 // Copyright 2009-2010 Sandia Corporation. Under the terms
00002 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
00003 // Government retains certain rights in this software.
00004 // 
00005 // Copyright (c) 2009-2010, Sandia Corporation
00006 // All rights reserved.
00007 // 
00008 // This file is part of the SST software package. For license
00009 // information, see the LICENSE file in the top level directory of the
00010 // distribution.
00011 
00012 
00013 #include <sst/elements/include/paramUtil.h>
00014 #include "sst/core/event.h"
00015 
00016 #define _EC_DBG( fmt, args... ) \
00017     m_dbg.write( "%s():%d: "fmt, __FUNCTION__, __LINE__, ##args)
00018 
00019 EVENTCHANNEL()::EventChannel( Component& comp, 
00020             Component::Params_t params, std::string name, int numVC ) :
00021     m_component( comp ),
00022     m_log( *new Log<  >( "INFO EventChannel: ", false ) ),
00023     m_dbg( *new Log< EVENTCHANNEL_DBG >( "EventChannel::", false ) )
00024 {
00025     _EC_DBG("\n");
00026 
00027     if ( params.find("info") != params.end() ) {
00028         if ( params["info"].compare("yes") == 0 ) {
00029             m_log.enable();
00030         }
00031     }
00032 
00033     bool dbgFlag = false;
00034     if ( params.find("debug") != params.end() ) {
00035         if ( params["debug"].compare("yes") == 0 ) {
00036             m_dbg.enable();
00037             dbgFlag = true;
00038         }
00039     }
00040 
00041 //     EventHandler_t*   handler = new EventHandler< EventChannel, bool, Event* >
00042 //                        ( this, &EventChannel::handler );
00043 
00044 //     if ( ! handler ) {
00045 //         _abort( EventChannel, "new EventHandler failed\n" );
00046 //     }
00047 
00048     m_log.write("creating link \"%s\"\n", name.c_str());
00049     Link* link = comp.configureLink( name, new Event::Handler<EventChannel>(this, &EventChannel::handler) );
00050     if (link == NULL) {
00051       printf("Unable to bring up memory Link!\n");
00052     }
00053 
00054     m_vcV.resize( numVC );
00055 
00056     int startCredit = 0;
00057     int threshold = 0;
00058     if ( params.find("initialCredit") != params.end() ) {
00059         startCredit = str2long( params["initialCredit"] );
00060     }
00061 
00062     for ( int i = 0; i < numVC; i++ ) {
00063         m_vcV[i] = new VirtChan( i, *link, comp.type, dbgFlag, 
00064                                             startCredit, threshold );
00065     }
00066     
00067 //     ClockHandler_t*     clockHandler;
00068 //     clockHandler = new EventHandler< EventChannel, bool, Cycle_t >
00069 //                                                 ( this, &EventChannel::clock );
00070 
00071     std::string frequency = "1GHz";
00072     if ( params.find("clock") != params.end() ) {
00073         frequency = params["clock"];
00074     }
00075 
00076     m_log.write("frequency=%s startCredit=%d\n",frequency.c_str(),startCredit );
00077 
00078 //     TimeConverter* tc = comp.registerClock( frequency, clockHandler );
00079     TimeConverter* tc =
00080         comp.registerClock( frequency, new Clock::Handler<EventChannel>(this, &EventChannel::clock) );
00081 
00082     if ( ! tc ) {
00083         _abort(XbarV2,"couldn't register clock handler");
00084     }
00085 }
00086 
00087 EVENTCHANNEL(bool)::clock( Cycle_t cycle )
00088 {
00089     for ( unsigned int i = 0; i < m_vcV.size(); i++ ) {
00090         m_vcV[i]->clock( cycle );
00091     }
00092     return false;
00093 }
00094 
00095 EVENTCHANNEL( void )::handler( Event* e )
00096 {
00097     event_t* event = static_cast< event_t* >( e );
00098     if ( size_t(event->virtChan) > m_vcV.size() ) {
00099         _abort(EventChannel,"invalid vc=%d\n", event->virtChan );
00100     } 
00101     return m_vcV[ event->virtChan ]->handler( event );
00102 }
00103 
00104 EVENTCHANNEL( inline bool )::ready( int credit, int vc )
00105 {
00106   if ( size_t(vc) > m_vcV.size() ) {
00107         _abort(EventChannel,"invalid vc=%d\n", vc );
00108     } 
00109     return m_vcV[ vc ]->ready( credit );
00110 }
00111 
00112 EVENTCHANNEL( inline bool )::send( eventT* event, int credit, int vc )
00113 {
00114   if ( size_t(vc) > m_vcV.size() ) {
00115     _abort(EventChannel,"invalid vc=%d\n", vc );
00116   } 
00117   return m_vcV[ vc ]->send( event, credit );
00118 }
00119 
00120 EVENTCHANNEL( inline bool )::recv( eventT** event, int vc  )
00121 {
00122   if ( size_t(vc) > m_vcV.size() ) {
00123         _abort(EventChannel,"invalid vc=%d\n", vc );
00124     } 
00125     return m_vcV[ vc ]->recv( event );
00126 }
00127 
00128 EVENTCHANNEL()::VirtChan::VirtChan( int vc, Link& link, std::string& name, 
00129                                 bool dbgFlag, int startCredit, int threshold ) :
00130     m_vc( vc ),
00131     m_link( link ),
00132     m_creditAvail( startCredit ),
00133     m_creditFreed( 0 ),
00134     m_creditThreshold( threshold ),
00135     m_name( name ),
00136     m_dbg( *new Log< EVENTCHANNEL_DBG > ("EventChannel::VirtChan::", dbgFlag) )
00137 {
00138     _EC_DBG("avail=%d thres=%d\n", m_creditAvail, m_creditThreshold );
00139 }
00140 
00141 EVENTCHANNEL( inline bool )::VirtChan::clock( Cycle_t cycle )
00142 {
00143     if ( ! m_outQ.empty() ) {
00144         _EC_DBG("%s: cycle=%lu send, event=%p\n", m_name.c_str(),
00145                             cycle,m_outQ.front() );
00146 
00147         m_link.Send( 0, m_outQ.front() );
00148         m_outQ.pop_front();
00149     }
00150 
00151     if ( m_creditFreed > m_creditThreshold ) 
00152     {
00153         event_t* event = new event_t;
00154 
00155         event->type   = event_t::CREDIT;
00156         event->credit = m_creditFreed;
00157         event->virtChan = m_vc;
00158 
00159         m_creditFreed = 0;
00160 
00161         _EC_DBG("%s: cycle=%lu send %d credits\n", 
00162                     m_name.c_str(), cycle, event->credit);
00163         m_link.Send( 0, event );
00164     }
00165     return false;
00166 }
00167 
00168 EVENTCHANNEL( inline void )::VirtChan::handler( event_t* event )
00169 {
00170     if ( event->type == event_t::EVENT ) {
00171         //_EC_DBG("%s: got event\n", m_name.c_str() );
00172         m_inQ.push_back( event );
00173     } else if ( event->type == event_t::CREDIT ) {
00174         m_creditAvail += event->credit;
00175         _EC_DBG("%s: got %d credits now avail %d\n",
00176                      m_name.c_str(), event->credit, m_creditAvail );
00177         delete event;
00178     } else {
00179         _abort( WireLink, "bad event type %d\n", event->type );
00180     }
00181     return;
00182 }
00183 
00184 EVENTCHANNEL( inline bool )::VirtChan::ready( int credit )
00185 {
00186    _EC_DBG("%s: credit=%d m_createAvail=%d\n", m_name.c_str(),
00187                                     credit, m_creditAvail);
00188    return ( (int)m_creditAvail >=  credit );
00189 }
00190 
00191 EVENTCHANNEL( inline bool )::VirtChan::send( eventT* event, int credit )
00192 {
00193   if ( (int)m_creditAvail < credit ) {
00194         _EC_DBG("%s: failed, credit=%d createAvail=%d\n", m_name.c_str(),
00195                                     credit, m_creditAvail);
00196         return false;
00197     }
00198     _EC_DBG("%s: need credit=%d createAvail=%d\n", m_name.c_str(),
00199                                     credit, m_creditAvail);
00200 
00201     event_t* cEvent = new event_t;
00202     cEvent->virtChan = m_vc;
00203     cEvent->event  = event;
00204     cEvent->type   = event_t::EVENT;
00205     cEvent->credit = credit;
00206 
00207     m_outQ.push_back( cEvent );
00208 
00209     m_creditAvail -= credit;
00210 
00211     return true;
00212 }
00213 
00214 EVENTCHANNEL( inline bool )::VirtChan::recv( eventT** event )
00215 {
00216     if ( m_inQ.empty() ) {
00217         return false;
00218     }
00219     *event = m_inQ.front()->event;
00220     
00221     m_creditFreed += m_inQ.front()->credit;
00222     _EC_DBG("%s: creditFreed=%d\n",m_name.c_str(), m_creditFreed);
00223 
00224     delete m_inQ.front();
00225     m_inQ.pop_front();
00226 
00227     return true;
00228 }

Generated on Fri Oct 22 2010 11:02:25 for SST by  doxygen 1.7.1