#include <GlobalTraceManager.h>
If trace includes user action, send actions to application
Public Member Functions | |
GlobalTraceManager () | |
~GlobalTraceManager () | |
void | handleMessage (cMessage *msg) |
void | initialize (int stage) |
Protected Member Functions | |
void | readNextBlock () |
void | scheduleNextEvent (double time, int nodeId, char *buf, int line) |
void | createNode (int nodeId) |
void | deleteNode (int nodeId) |
cGate * | getAppGateById (int nodeId) |
Protected Attributes | |
UnderlayConfigurator * | underlayConfigurator |
BootstrapOracle * | bootstrapOracle |
pointer to BootstrapOracle | |
Private Attributes | |
int | fd |
int | filesize |
int | chunksize |
int | remain |
int | marginsize |
int | offset |
char * | buf |
char * | start |
cMessage * | nextRead |
Static Private Attributes | |
static const int | readPages = 32 |
GlobalTraceManager::GlobalTraceManager | ( | ) |
GlobalTraceManager::~GlobalTraceManager | ( | ) |
void GlobalTraceManager::handleMessage | ( | cMessage * | msg | ) |
00172 { 00173 if (!msg->isSelfMessage()) { 00174 delete msg; 00175 return; 00176 } else if ( msg == nextRead ) { 00177 readNextBlock(); 00178 return; 00179 } 00180 00181 GlobalTraceManagerMessage* traceMsg = check_and_cast<GlobalTraceManagerMessage*>(msg); 00182 00183 if (strstr(traceMsg->name(), "JOIN") == traceMsg->name()) { 00184 createNode(traceMsg->getInternalNodeId()); 00185 } else if (strstr(traceMsg->name(), "LEAVE") == traceMsg->name()) { 00186 deleteNode(traceMsg->getInternalNodeId()); 00187 } else if (strstr(traceMsg->name(), "CONNECT_NODETYPES") == traceMsg->name()) { 00188 std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector(); 00189 00190 if (strVec.size() != 3) { 00191 throw new cException("GlobalTraceManager::" 00192 "handleMessage(): Invalid command"); 00193 } 00194 00195 int firstNodeType = atoi(strVec[1].c_str()); 00196 int secondNodeType = atoi(strVec[2].c_str()); 00197 00198 bootstrapOracle->connectNodeTypes(firstNodeType, secondNodeType); 00199 } else if (strstr(traceMsg->name(), "DISCONNECT_NODETYPES") == traceMsg->name()) { 00200 std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector(); 00201 00202 if (strVec.size() != 3) { 00203 throw new cException("GlobalTraceManager::" 00204 "handleMessage(): Invalid command"); 00205 } 00206 00207 int firstNodeType = atoi(strVec[1].c_str()); 00208 int secondNodeType = atoi(strVec[2].c_str()); 00209 00210 bootstrapOracle->disconnectNodeTypes(firstNodeType, secondNodeType); 00211 } else if (strstr(traceMsg->name(), "MERGE_BOOTSTRAPNODES") == traceMsg->name()) { 00212 std::vector<std::string> strVec = cStringTokenizer(msg->name()).asVector(); 00213 00214 if (strVec.size() != 4) { 00215 throw new cException("GlobalTraceManager::" 00216 "handleMessage(): Invalid command"); 00217 } 00218 00219 int toPartition = atoi(strVec[1].c_str()); 00220 int fromPartition = atoi(strVec[2].c_str()); 00221 int numNodes = atoi(strVec[3].c_str()); 00222 00223 bootstrapOracle->mergeBootstrapNodes(toPartition, fromPartition, numNodes); 00224 } else { 00225 sendDirect(msg, 0, getAppGateById(traceMsg->getInternalNodeId())); 00226 return; // don't delete Message 00227 } 00228 00229 delete msg; 00230 }
void GlobalTraceManager::initialize | ( | int | stage | ) |
00040 { 00041 Enter_Method_Silent(); 00042 00043 // Nothing to do for us if there is no traceFile 00044 if (strlen(par("traceFile")) == 0) 00045 return; 00046 00047 underlayConfigurator = UnderlayConfiguratorAccess().get(); 00048 bootstrapOracle = BootstrapOracleAccess().get(); 00049 00050 offset = 0; 00051 00052 // Open file and get size 00053 fd = open(par("traceFile"), O_RDONLY); 00054 00055 if (!fd) { 00056 throw new cException(("Cant open file " + std::string(par("traceFile")) + 00057 std::string(strerror(errno))).c_str()); 00058 } 00059 00060 struct stat filestat; 00061 00062 if (fstat(fd, &filestat)) { 00063 throw new cException(("Error calling stat: " + std::string(strerror(errno))).c_str()); 00064 } 00065 00066 filesize = filestat.st_size; 00067 remain = filesize; 00068 EV << "Successfully opened trace file " << std::string(par("traceFile")) 00069 << ". Size: " << filesize << endl; 00070 00071 nextRead = new cMessage("NextRead"); 00072 scheduleAt(0, nextRead); 00073 00074 }
void GlobalTraceManager::readNextBlock | ( | ) | [protected] |
Referenced by handleMessage().
00087 { 00088 double time = -1; 00089 int nodeID; 00090 char* bufend; 00091 int line = 1; 00092 00093 if (remain > 0) { 00094 // If rest of the file is bigger than maximal chunk size, set chunksize 00095 // to max; the last mapped page is used as margin. 00096 // Else map the whole remainder od the file at a time, no margin is needed 00097 // in this case 00098 chunksize = remain < getpagesize()*readPages ? remain : getpagesize()*readPages; 00099 marginsize = remain == chunksize ? 0 : getpagesize(); 00100 00101 start = (char*) mmap(0, chunksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, filesize - remain); 00102 00103 if (start == MAP_FAILED) { 00104 throw new cException(("Error mapping file to memory:" + 00105 std::string(strerror(errno))).c_str()); 00106 } 00107 00108 buf = start + offset; 00109 // While the read pointer has not reached the margin, continue parsing 00110 while( buf < start + chunksize - marginsize) { // FIXME: Assuming max line length of getpagesize() 00111 00112 time = strtod(buf, &bufend); 00113 if (bufend==buf) { 00114 throw new cException("Error parsing file: Expected time as double"); 00115 } 00116 buf = bufend; 00117 00118 nodeID = strtol(buf, &bufend, 0); 00119 if (bufend==buf) { 00120 throw new cException("Error parsing file: Expected ID as long int"); 00121 } 00122 buf = bufend; 00123 00124 while( isspace(buf[0]) ) buf++; 00125 00126 bufend = strchr(buf, '\n'); 00127 if (!bufend) { 00128 throw new cException("Error parsing file: Missing command or no newline at end of line!"); 00129 } 00130 bufend[0]='\0'; 00131 scheduleNextEvent(time, nodeID, buf, line++); 00132 buf += strlen(buf)+1; 00133 00134 while( isspace(buf[0]) ) buf++; 00135 } 00136 00137 // Compute offset for the next read 00138 offset = (buf - start) - (chunksize - marginsize); 00139 remain -= chunksize - marginsize; 00140 munmap( start, chunksize ); 00141 } 00142 00143 if (time > 0) { 00144 scheduleAt(time, nextRead); 00145 } else { 00146 // TODO: Schedule simulation end? 00147 } 00148 }
void GlobalTraceManager::scheduleNextEvent | ( | double | time, | |
int | nodeId, | |||
char * | buf, | |||
int | line | |||
) | [protected] |
Referenced by readNextBlock().
00151 { 00152 GlobalTraceManagerMessage* msg = new GlobalTraceManagerMessage(buf); 00153 00154 msg->setInternalNodeId(nodeId); 00155 msg->setLineNumber(line); 00156 scheduleAt(time, msg); 00157 }
void GlobalTraceManager::createNode | ( | int | nodeId | ) | [protected] |
Referenced by handleMessage().
00160 { 00161 check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0)) 00162 ->createNode(nodeId); 00163 }
void GlobalTraceManager::deleteNode | ( | int | nodeId | ) | [protected] |
Referenced by handleMessage().
00166 { 00167 check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0)) 00168 ->deleteNode(nodeId); 00169 }
cGate * GlobalTraceManager::getAppGateById | ( | int | nodeId | ) | [protected] |
Referenced by handleMessage().
00232 { 00233 return check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0)) 00234 ->getAppGateById(nodeId); 00235 }
Referenced by createNode(), deleteNode(), getAppGateById(), and initialize().
BootstrapOracle* GlobalTraceManager::bootstrapOracle [protected] |
int GlobalTraceManager::fd [private] |
Referenced by initialize(), and readNextBlock().
int GlobalTraceManager::filesize [private] |
Referenced by initialize(), and readNextBlock().
int GlobalTraceManager::chunksize [private] |
Referenced by readNextBlock().
int GlobalTraceManager::remain [private] |
Referenced by initialize(), and readNextBlock().
int GlobalTraceManager::marginsize [private] |
Referenced by readNextBlock().
int GlobalTraceManager::offset [private] |
Referenced by initialize(), and readNextBlock().
char* GlobalTraceManager::buf [private] |
Referenced by readNextBlock().
char * GlobalTraceManager::start [private] |
Referenced by readNextBlock().
const int GlobalTraceManager::readPages = 32 [static, private] |
Referenced by readNextBlock().
cMessage* GlobalTraceManager::nextRead [private] |
Referenced by GlobalTraceManager(), handleMessage(), initialize(), readNextBlock(), and ~GlobalTraceManager().