GlobalTraceManager.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <fcntl.h>
00027 #include <errno.h>
00028 #ifndef _WIN32
00029 #include <sys/mman.h>
00030 #endif
00031
00032 #include <UnderlayConfiguratorAccess.h>
00033 #include <GlobalNodeListAccess.h>
00034 #include <GlobalTraceManager_m.h>
00035 #include <TraceChurn.h>
00036
00037 #include "GlobalTraceManager.h"
00038
00039 Define_Module(GlobalTraceManager);
00040
00041 void GlobalTraceManager::initialize(int stage)
00042 {
00043 Enter_Method_Silent();
00044
00045
00046 if (strlen(par("traceFile")) == 0)
00047 return;
00048
00049 underlayConfigurator = UnderlayConfiguratorAccess().get();
00050 globalNodeList = GlobalNodeListAccess().get();
00051
00052 offset = 0;
00053
00054
00055 fd = open(par("traceFile"), O_RDONLY);
00056
00057 if (!fd) {
00058 throw cRuntimeError(("Can't open file " + par("traceFile").stdstringValue() +
00059 std::string(strerror(errno))).c_str());
00060 }
00061
00062 struct stat filestat;
00063
00064 if (fstat(fd, &filestat)) {
00065 throw cRuntimeError(("Error calling stat: " + std::string(strerror(errno))).c_str());
00066 }
00067
00068 filesize = filestat.st_size;
00069 remain = filesize;
00070 EV << "[GlobalTraceManager::initialize()]\n"
00071 << " Successfully opened trace file " << par("traceFile").stdstringValue()
00072 << ". Size: " << filesize
00073 << endl;
00074
00075 nextRead = new cMessage("NextRead");
00076 scheduleAt(0, nextRead);
00077
00078 }
00079
00080 GlobalTraceManager::GlobalTraceManager()
00081 {
00082 nextRead = NULL;
00083 }
00084
00085 GlobalTraceManager::~GlobalTraceManager()
00086 {
00087 cancelAndDelete(nextRead);
00088 }
00089
00090 void GlobalTraceManager::readNextBlock()
00091 {
00092 #ifdef _WIN32
00093
00094 throw cRuntimeError("GlobalTraceManager::readNextBlock():"
00095 "Not available on WIN32 yet!");
00096 #else
00097 double time = -1;
00098 int nodeID;
00099 char* bufend;
00100 int line = 1;
00101
00102 if (remain > 0) {
00103
00104
00105
00106
00107 chunksize = remain < getpagesize()*readPages ? remain : getpagesize()*readPages;
00108 marginsize = remain == chunksize ? 0 : getpagesize();
00109
00110 start = (char*) mmap(0, chunksize, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, filesize - remain);
00111
00112 if (start == MAP_FAILED) {
00113 throw cRuntimeError(("Error mapping file to memory:" +
00114 std::string(strerror(errno))).c_str());
00115 }
00116
00117 buf = start + offset;
00118
00119 while( buf < start + chunksize - marginsize) {
00120
00121 time = strtod(buf, &bufend);
00122 if (bufend==buf) {
00123 throw cRuntimeError("Error parsing file: Expected time as double");
00124 }
00125 buf = bufend;
00126
00127 nodeID = strtol(buf, &bufend, 0);
00128 if (bufend==buf) {
00129 throw cRuntimeError("Error parsing file: Expected ID as long int");
00130 }
00131 buf = bufend;
00132
00133 while( isspace(buf[0]) ) buf++;
00134
00135 bufend = strchr(buf, '\n');
00136 if (!bufend) {
00137 throw cRuntimeError("Error parsing file: Missing command or no newline at end of line!");
00138 }
00139 bufend[0]='\0';
00140 scheduleNextEvent(time, nodeID, buf, line++);
00141 buf += strlen(buf)+1;
00142
00143 while( isspace(buf[0]) ) buf++;
00144 }
00145
00146
00147 offset = (buf - start) - (chunksize - marginsize);
00148 remain -= chunksize - marginsize;
00149 munmap( start, chunksize );
00150 }
00151
00152 if (time > 0) {
00153 scheduleAt(time, nextRead);
00154 } else {
00155
00156 }
00157 #endif
00158 }
00159
00160 void GlobalTraceManager::scheduleNextEvent(double time, int nodeId, char* buf, int line)
00161 {
00162 GlobalTraceManagerMessage* msg = new GlobalTraceManagerMessage(buf);
00163
00164 msg->setInternalNodeId(nodeId);
00165 msg->setLineNumber(line);
00166 scheduleAt(time, msg);
00167 }
00168
00169 void GlobalTraceManager::createNode(int nodeId)
00170 {
00171 check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00172 ->createNode(nodeId);
00173 }
00174
00175 void GlobalTraceManager::deleteNode(int nodeId)
00176 {
00177
00178 check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00179 ->deleteNode(nodeId);
00180 }
00181
00182 void GlobalTraceManager::handleMessage(cMessage* msg)
00183 {
00184 if (!msg->isSelfMessage()) {
00185 delete msg;
00186 return;
00187 } else if ( msg == nextRead ) {
00188 readNextBlock();
00189 return;
00190 }
00191
00192 GlobalTraceManagerMessage* traceMsg = check_and_cast<GlobalTraceManagerMessage*>(msg);
00193
00194 if (strstr(traceMsg->getName(), "JOIN") == traceMsg->getName()) {
00195 createNode(traceMsg->getInternalNodeId());
00196 } else if (strstr(traceMsg->getName(), "LEAVE") == traceMsg->getName()) {
00197 deleteNode(traceMsg->getInternalNodeId());
00198 } else if (strstr(traceMsg->getName(), "CONNECT_NODETYPES") == traceMsg->getName()) {
00199 std::vector<std::string> strVec = cStringTokenizer(msg->getName()).asVector();
00200
00201 if (strVec.size() != 3) {
00202 throw cRuntimeError("GlobalTraceManager::"
00203 "handleMessage(): Invalid command");
00204 }
00205
00206 int firstNodeType = atoi(strVec[1].c_str());
00207 int secondNodeType = atoi(strVec[2].c_str());
00208
00209 globalNodeList->connectNodeTypes(firstNodeType, secondNodeType);
00210 } else if (strstr(traceMsg->getName(), "DISCONNECT_NODETYPES") == traceMsg->getName()) {
00211 std::vector<std::string> strVec = cStringTokenizer(msg->getName()).asVector();
00212
00213 if (strVec.size() != 3) {
00214 throw cRuntimeError("GlobalTraceManager::"
00215 "handleMessage(): Invalid command");
00216 }
00217
00218 int firstNodeType = atoi(strVec[1].c_str());
00219 int secondNodeType = atoi(strVec[2].c_str());
00220
00221 globalNodeList->disconnectNodeTypes(firstNodeType, secondNodeType);
00222 } else if (strstr(traceMsg->getName(), "MERGE_BOOTSTRAPNODES") == traceMsg->getName()) {
00223 std::vector<std::string> strVec = cStringTokenizer(msg->getName()).asVector();
00224
00225 if (strVec.size() != 4) {
00226 throw cRuntimeError("GlobalTraceManager::"
00227 "handleMessage(): Invalid command");
00228 }
00229
00230 int toPartition = atoi(strVec[1].c_str());
00231 int fromPartition = atoi(strVec[2].c_str());
00232 int numNodes = atoi(strVec[3].c_str());
00233
00234 globalNodeList->mergeBootstrapNodes(toPartition, fromPartition, numNodes);
00235 } else {
00236 sendDirect(msg, getAppGateById(traceMsg->getInternalNodeId()));
00237 return;
00238 }
00239
00240 delete msg;
00241 }
00242
00243 cGate* GlobalTraceManager::getAppGateById(int nodeId) {
00244 return check_and_cast<TraceChurn*>(underlayConfigurator->getChurnGenerator(0))
00245 ->getAppGateById(nodeId);
00246 }
00247