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

sst/elements/include/memoryChannel.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 #ifndef _MEMORY_CHANNEL_H
00014 #define _MEMORY_CHANNEL_H
00015 
00016 #ifndef MEMORYCHANNEL_DBG
00017 #define MEMORYCHANNEL_DBG 0
00018 #endif
00019 
00020 #define _MC_DBG( fmt, args... ) \
00021     m_dbg.write( "%s():%d: "fmt, __FUNCTION__, __LINE__, ##args)
00022 
00023 #include <sst/elements/include/eventChannel.h>
00024 #include <map>
00025 
00026 using namespace SST;
00027 
00028 template < typename addrT = unsigned long,
00029             typename dataT = unsigned long >
00030 struct MemEvent 
00031 {
00032   typedef enum { READ = 0, WRITE, RMW, INV_REQ } reqType_t;
00033         typedef enum { REQUEST = 0, RESPONSE, INV_MSG } msgType_t;
00034 
00035         typedef dataT data_t;
00036         typedef addrT addr_t;
00037 
00038         reqType_t reqType;
00039         msgType_t msgType;
00040         addr_t    addr;
00041         data_t    data;
00042 };
00043 
00044 template < typename addrT = unsigned long,
00045             typename cookieT = unsigned long,
00046             typename dataT = unsigned long >
00047 class MemoryChannel : 
00048     public EventChannel< MemEvent< addrT, dataT > >
00049 {
00050     public: // types
00051 
00052         typedef MemEvent< addrT, dataT >    event_t;
00053         typedef typename event_t::addr_t    addr_t;
00054         typedef dataT                       data_t;
00055         typedef cookieT                     cookie_t;
00056 
00057     private: // types
00058         typedef std::multimap< addr_t, cookie_t>            reqMap_t;
00059         typedef EventChannel< MemEvent< addrT, dataT > >    eventChannel_t;
00060 
00061     public: // functions
00062 
00063   virtual ~MemoryChannel() {;}
00064         MemoryChannel( Component& comp, Component::Params_t params,
00065                                                         std::string name )  :
00066             eventChannel_t( comp, params, name, 2 ),
00067             m_readReqCredit( 0 ),
00068             m_readRespCredit( 0 ),
00069             m_writeReqCredit( 0 ),
00070             m_writeRespCredit( 0 ),
00071             m_log( *new Log<>( "INFO MemoryChannel::", false ) ),
00072             m_dbg( *new Log< MEMORYCHANNEL_DBG >( "MemoryChannel::", false ) )
00073         {
00074             if ( params.find("debug") != params.end() ) {
00075                 if ( params["debug"].compare("yes") == 0 ) {
00076                     m_dbg.enable();
00077                 }
00078             }
00079 
00080             if ( params.find("info") != params.end() ) {
00081                 if ( params["info"].compare("yes") == 0 ) {
00082                     m_log.enable();
00083                 }
00084             }
00085 
00086             if ( params.find("readReqCredit") != params.end() ) {
00087                 m_readReqCredit = str2long( params["readReqCredit"] ); 
00088             }
00089             if ( params.find("writeReqCredit") != params.end() ) {
00090                 m_writeReqCredit = str2long( params["writeReqCredit"] ); 
00091             }
00092             if ( params.find("readRespCredit") != params.end() ) {
00093                 m_readRespCredit = str2long( params["readRespCredit"] ); 
00094             }
00095             if ( params.find("writeRespCredit") != params.end() ) {
00096                 m_writeRespCredit = str2long( params["writeRespCredit"] ); 
00097             }
00098 
00099             m_log.write( "readReqCredit=%d readRespCredit=%d\n",
00100                         m_readReqCredit, m_readRespCredit );
00101             m_log.write( "writeReqCredit=%d writeRespCredit=%d\n",
00102                         m_writeReqCredit, m_writeRespCredit );
00103         }
00104 
00105         virtual inline bool ready( typename event_t::msgType_t msgType,
00106                     typename event_t::reqType_t reqType = event_t::READ )
00107         {
00108             return eventChannel_t::ready( 
00109                                 calcCredit( msgType, reqType ), msgType );
00110         }
00111 
00112         virtual inline bool send( event_t* event, cookie_t cookie = 0 )
00113         {
00114             return send( event, event->msgType, event->reqType,
00115                                                     event->addr, cookie );
00116         }
00117 
00118         virtual inline bool recv( event_t** event, cookie_t* cookie = 0 )
00119         {
00120             if ( recv( event, event_t::RESPONSE, cookie ) ) {
00121                 return true;
00122             }
00123             return recv( event, event_t::REQUEST, cookie );
00124         }
00125 
00126         virtual inline bool send( event_t* event, 
00127                                     typename event_t::msgType_t msgType,
00128                                     typename event_t::reqType_t reqType,
00129                                     addr_t addr, cookie_t cookie = 0 )
00130         {
00131             _MC_DBG("event=%p cookie=%#lx type=%d:%d \n", event, cookie, 
00132                                 msgType, reqType );
00133 
00134             int tokens = calcCredit( msgType, reqType );
00135             if ( ! eventChannel_t::ready( tokens, msgType ) ) {
00136                 return false;
00137             }
00138 
00139             if ( cookie ) {
00140                 storeCookie( reqType, cookie, addr );
00141             } 
00142 
00143             return eventChannel_t::send( event, tokens, msgType );
00144         }
00145 
00146         virtual inline bool recv( event_t** event,
00147                                         typename event_t::msgType_t type,
00148                                         cookie_t* cookie = 0 )
00149         {
00150             if ( ! eventChannel_t::recv( event, type ) ) {
00151                 return false;
00152             }
00153 
00154             if ( cookie && (*event)->msgType == event_t::RESPONSE ) {
00155                 *cookie = findCookie( (*event)->reqType, (*event)->addr );
00156             }
00157 
00158             _MC_DBG("event=%p cookie=%#lx\n", *event, cookie );
00159             return true;
00160         }
00161 
00162     private:
00163         inline int calcCredit( typename event_t::msgType_t msgType,
00164                                 typename event_t::reqType_t reqType )
00165         {
00166             if ( msgType == event_t::REQUEST )  {
00167                 if ( reqType == event_t::READ ) {
00168                     return m_readReqCredit;
00169                 } else {
00170                     return m_writeReqCredit;
00171                 }
00172             } else {
00173                 if ( reqType == event_t::READ ) {
00174                     return m_readRespCredit;
00175                 } else {
00176                     return m_writeRespCredit;
00177                 }
00178             }
00179         } 
00180 
00181         inline void storeCookie( typename event_t::reqType_t type,
00182                                     cookie_t cookie, addr_t addr )
00183         {
00184             if ( type == event_t::WRITE )  {
00185                 m_writeReqMap.insert( std::make_pair( addr, cookie ) );
00186             } else {
00187                 m_readReqMap.insert( std::make_pair( addr, cookie ) );
00188             }
00189         }
00190 
00191         inline cookie_t findCookie( typename event_t::reqType_t type,
00192                                     addr_t addr )
00193         {
00194             typename reqMap_t::iterator iter;
00195             if ( type == event_t::WRITE )  {
00196                 iter = m_writeReqMap.find( addr );
00197                 if ( iter != m_writeReqMap.end() ) {
00198                     m_writeReqMap.erase(iter);
00199                     return iter->second;
00200                 }
00201             } else {
00202                 iter = m_readReqMap.find( addr );
00203                 if ( iter != m_readReqMap.end() ) {
00204                     m_readReqMap.erase(iter);
00205                     return iter->second;
00206                 }
00207             }
00208             return 0;
00209         }
00210 
00211     private: // data
00212 
00213         reqMap_t    m_writeReqMap;
00214         reqMap_t    m_readReqMap;
00215         int         m_readReqCredit;
00216         int         m_readRespCredit;
00217         int         m_writeReqCredit;
00218         int         m_writeRespCredit;
00219 
00220         Log<>&                      m_log;
00221         Log< MEMORYCHANNEL_DBG >&   m_dbg;
00222 };
00223 
00224 #endif

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