PCMHostInfo.cpp

Go to the documentation of this file.
00001 //
00002 // This source file is a part of ParCompMark
00003 // Parallel Compositing Benchmark Framework
00004 //
00005 // for latest info see http://parcompmark.sourceforge.net
00006 
00007 //
00008 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00009 // 
00010 // This program is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU General Public License
00012 // as published by the Free Software Foundation; either version 2
00013 // of the License, or (at your option) any later version.
00014 // 
00015 // This program is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 // GNU General Public License for more details.
00019 // 
00020 // You should have received a copy of the GNU General Public License
00021 // along with this program; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023 
00024 //
00025 // Inner includes
00026 //
00027 
00028 #include "../include/PCMHostInfo.h"
00029 
00030 #include "../include/PCMHost.h"
00031 
00032 namespace ParCompMark
00033 {
00034 
00035   //
00036   // Constructors & destructor
00037   //
00038 
00039   HostInfo::HostInfo(const std::string & name, const OutputNode::NodeType & type):
00040         // Parent initialize 
00041   OutputNode(name               /* Name of the host */
00042            , type               /* Type of the host node */
00043         )
00044         // You have to initialize the following attributes:
00045         // - mCPUs
00046         // - mGPUs
00047         // - mNetIDNames
00048         // - mPCLibVersion
00049         // - mPCNumNetworks
00050         // - mPCVendor
00051         // - mPCExtensions
00052         // - mVolatileFrameletLimit
00053         // - mRetainOutputLimit
00054   {
00055 
00056         setAttribute("name", name);
00057 
00058         //Create CPUs
00059         mCPUs = new Container < CPU, Mutex >;
00060 
00061         //Create GPUs
00062         mGPUs = new Container < GPU, Mutex >;
00063 
00064         mNetIDNames = new Container < HostInfo::NetIDName, DummyLock >;
00065 
00066         mPCLibVersion = "";
00067         mPCNumNetworks = 0;
00068         mPCVendor = "";
00069         mPCExtensions = "";
00070         mVolatileFrameletLimit = 0;
00071         mRetainOutputLimit = 0;
00072 
00073   }
00074 
00075  /*----------------------------------------------------------------------*/
00076 
00077   HostInfo::~HostInfo()
00078   {
00079         if(mCPUs.isNotNull())
00080          mCPUs.kill();
00081 
00082         if(mGPUs.isNotNull())
00083          mGPUs.kill();
00084 
00085         if(mNetIDNames.isNotNull())
00086          mNetIDNames.kill();
00087   }
00088 
00089  /*----------------------------------------------------------------------*/
00090 
00091   //
00092   // Class methods
00093   //
00094 
00095   HostInfo::Pointer HostInfo::parseXML(TiXmlElement * &tiHostinfo)
00096   {
00097         std::string hostNamespace;
00098         std::string hostName;
00099 
00100         //string separation
00101         std::string hostTag(tiHostinfo->Value());
00102         std::string::size_type pos = hostTag.find(":");
00103         if(pos != std::string::npos)
00104         {
00105          hostNamespace = hostTag.substr(0, pos);
00106          hostName = hostTag.substr(pos + 1);
00107         } else
00108         {
00109          hostNamespace = "info";
00110          hostName = "NoNameHOSTINFO";
00111         }
00112 
00113         OutputNode::NodeType nspace;
00114 
00115         if(hostNamespace == "def")
00116          nspace = OutputNode::DEFINITION;
00117         else if(hostNamespace == "info")
00118          nspace = OutputNode::INFORMATION;
00119         else if(hostNamespace == "ref")
00120          nspace = OutputNode::REFERENCE;
00121         else if(hostNamespace == "stat")
00122          nspace = OutputNode::STATISTICS;
00123         else
00124          nspace = OutputNode::INFORMATION;
00125 
00126         HostInfo::Pointer myHostInfo = HostInfo::Pointer(new HostInfo(hostName, nspace));
00127 
00128         //First parameter belonging to HostInfo
00129         TiXmlElement *tiParam = tiHostinfo->FirstChildElement();
00130 
00131         //save current HostInfo information to class variables
00132         for(; tiParam != NULL; tiParam = tiParam->NextSiblingElement())
00133         {
00134 
00135          //current parameter name
00136          std::string name = "";
00137 
00138          //current parameter value
00139          std::string value = "";
00140 
00141          //current tag value
00142          std::string tagName = "";
00143 
00144          //get name and value parameters from current xml element
00145          if((tiParam->Attribute("name") != NULL) && (tiParam->Attribute("value") != NULL))
00146          {
00147                 name = tiParam->Attribute("name");
00148                 value = tiParam->Attribute("value");
00149          }
00150          //get value of current xml element
00151          if(tiParam->Value() != NULL)
00152          {
00153                 tagName = tiParam->Value();
00154          }
00155 
00156          if(name.compare("pc-library-version") == 0)
00157          {
00158                 myHostInfo->mPCLibVersion = value;
00159          } else if(tagName.find("network-ids-names") != std::string::npos)
00160          {
00161 
00162                 TiXmlElement *tiNetworkIdNames = tiParam->FirstChildElement();
00163 
00164                 for(; tiNetworkIdNames != NULL; tiNetworkIdNames = tiNetworkIdNames->NextSiblingElement())
00165                 {
00166 
00167                  std::string networkId = tiNetworkIdNames->Attribute("id");
00168                  std::string networkName = tiNetworkIdNames->Attribute("name");
00169 
00170                  std::stringstream strStream;
00171                  PCint iNum;
00172 
00173                  strStream << networkId;
00174                  strStream >> iNum;
00175 
00176                  HostInfo::NetIDName::Pointer myNetIDName = HostInfo::NetIDName::Pointer(new HostInfo::NetIDName());
00177 
00178                  myNetIDName->ID = iNum;
00179                  myNetIDName->name = networkName;
00180 
00181                  myHostInfo->mNetIDNames->add(myNetIDName->name, myNetIDName);
00182 
00183                 }
00184 
00185          } else if(name.compare("pc-vendor") == 0)
00186          {
00187                 myHostInfo->mPCVendor = value;
00188          } else if(name.compare("pc-extensions") == 0)
00189          {
00190                 myHostInfo->mPCExtensions = value;
00191          } else if(name.compare("pc-number-networks") == 0)
00192          {
00193                 std::stringstream strStream;
00194                 int iNum;
00195 
00196                 strStream << value;
00197                 strStream >> iNum;
00198 
00199                 myHostInfo->mPCNumNetworks = iNum;
00200          } else if(name.compare("pc-volatile-framelet-limit") == 0)
00201          {
00202                 std::stringstream strStream;
00203                 int iNum;
00204 
00205                 strStream << value;
00206                 strStream >> iNum;
00207 
00208                 myHostInfo->mVolatileFrameletLimit = iNum;
00209          } else if(name.compare("pc-retain-ouput-limit") == 0)
00210          {
00211                 std::stringstream strStream;
00212                 int iNum;
00213 
00214                 strStream << value;
00215                 strStream >> iNum;
00216 
00217                 myHostInfo->mRetainOutputLimit = iNum;
00218          } else if(tagName.find("CPUs") != std::string::npos)
00219          {
00220 
00221                 TiXmlElement *tiCPU = tiParam->FirstChildElement();
00222 
00223                 for(; tiCPU != NULL; tiCPU = tiCPU->NextSiblingElement())
00224                 {
00225 
00226                  CPU::Pointer currentCPU = CPU::parseXML(tiCPU);
00227 
00228                  if(currentCPU.isNotNull())
00229                  {
00230                         myHostInfo->mCPUs->add(currentCPU->getName(), currentCPU);
00231                  }
00232 
00233                 }
00234          } else if(tagName.find("GPUs") != std::string::npos)
00235          {
00236                 TiXmlElement *tiGPU = tiParam->FirstChildElement();
00237 
00238                 for(; tiGPU != NULL; tiGPU = tiGPU->NextSiblingElement())
00239                 {
00240 
00241                  GPU::Pointer currentGPU = GPU::parseXML(tiGPU);
00242 
00243                  if(currentGPU.isNotNull())
00244                  {
00245                         myHostInfo->mGPUs->add(currentGPU->getName(), currentGPU);
00246                  }
00247 
00248                 }
00249          }
00250 
00251         }
00252 
00253         return HostInfo::Pointer(myHostInfo);
00254   }
00255 
00256  /*----------------------------------------------------------------------*/
00257 
00258   //
00259   // Methods
00260   //
00261 
00262   void HostInfo::refreshData()
00263   {
00264 
00265         PCerr err;
00266 
00267         OutputNode::Pointer p;
00268 
00269         char c[256];
00270         PCstring strValue;
00271         PCint intValue;
00272 
00294         if((err = pcSystemGetInteger(PC_NUM_NETWORKS, 0, &intValue)))
00295         {
00296          Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00297         }
00298 
00299         mPCNumNetworks = intValue;
00300         sprintf(c, "%d", intValue);
00301         p = createChildNode("param", OutputNode::INFORMATION);
00302         p->setAttribute("name", "pc-number-networks");
00303         p->setAttribute("value", c);
00304 
00305         OutputNode::Pointer net = createChildNode("network-ids-names", OutputNode::INFORMATION);
00306 
00307         for(int i = 0; i < mPCNumNetworks; i++)
00308         {
00309 
00310          if((err = pcSystemGetInteger(PC_NETWORK_ID, i, &intValue)))
00311          {
00312                 Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00313          }
00314 
00315          if((err = pcSystemGetString(PC_NETWORK_NAME, i, &strValue)))
00316          {
00317                 Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00318          }
00319 
00320          NetIDName::Pointer n = NetIDName::Pointer(new NetIDName);
00321 
00322          n->ID = intValue;
00323          n->name = strValue;
00324 
00325          mNetIDNames->add(strValue, n);
00326 
00327          sprintf(c, "%d", intValue);
00328          std::string s1, s2;
00329          s1 = c;
00330          s2 = strValue;
00331          p = net->createChildNode("network-id-name", OutputNode::INFORMATION);
00332          p->setAttribute("name", s2);
00333          p->setAttribute("id", s1);
00334         }
00335 
00336         if((err = pcSystemGetString(PC_VENDOR, 0, &strValue)))
00337         {
00338          Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00339         }
00340 
00341         mPCVendor = strValue;
00342         p = createChildNode("param", OutputNode::INFORMATION);
00343         p->setAttribute("name", "pc-vendor");
00344         p->setAttribute("value", strValue);
00345 
00346         if((err = pcSystemGetString(PC_EXTENSIONS, 0, &strValue)))
00347         {
00348          Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00349         }
00350         mPCExtensions = strValue;
00351         p = createChildNode("param", OutputNode::INFORMATION);
00352         p->setAttribute("name", "pc-extensions");
00353         p->setAttribute("value", strValue);
00354 
00355         if((err = pcSystemGetInteger(PC_VOLATILE_FRAMELET_LIMIT, 0, &intValue)))
00356         {
00357          Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00358         }
00359 
00360         mVolatileFrameletLimit = intValue;
00361         sprintf(c, "%d", intValue);
00362         p = createChildNode("param", OutputNode::INFORMATION);
00363         p->setAttribute("name", "pc-volatile-framelet-limit");
00364         p->setAttribute("value", c);
00365 
00366         if((err = pcSystemGetInteger(PC_RETAIN_OUTPUT_LIMIT, 0, &intValue)))
00367         {
00368          Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00369         }
00370 
00371         mRetainOutputLimit = intValue;
00372         sprintf(c, "%d", intValue);
00373         p = createChildNode("param", OutputNode::INFORMATION);
00374         p->setAttribute("name", "pc-retain-ouput-limit");
00375         p->setAttribute("value", c);
00376         /*
00377          * if(PCerr err = pcSessionDestroy() != PC_NO_ERROR)
00378          * Except(INTERNAL_ERROR, "HostInfo::refreshData()", pcGetErrorString(err));
00379          *///mHostInfo->serialize2XML();
00380 
00385         OutputNode::Pointer cpus = createChildNode("CPUs", OutputNode::INFORMATION);
00386         refreshCPUs(cpus);
00387         OutputNode::Pointer gpus = createChildNode("GPUs", OutputNode::INFORMATION);
00388         refreshGPUs(gpus);
00389 
00390   }
00391 
00392  /*----------------------------------------------------------------------*/
00393 
00394   void HostInfo::refreshCPUs(OutputNode::Pointer & cpus)
00395   {
00396 
00397         char c;
00398         char type[256],
00399         value[256];
00400         int i = 0;
00401 
00402         CPU::Pointer cpu;
00403 
00404         //CPU *cpu;
00405 
00406         std::string str;
00407 
00408         bool t = true;
00409 
00410         FileSystemManager::CFilePointer f = FileSystemManager::getInstance()->openFileC("/proc/cpuinfo");
00411 
00412         while(!feof(f.getPtr()))
00413         {
00414 
00415          fread(&c, sizeof(char), 1, f.getPtr());
00416 
00417          if(c == ':' && i != 0)
00418          {
00419                 type[i] = '\0';
00420                 i = 0;
00421                 fread(&c, sizeof(char), 1, f.getPtr());
00422                 t = false;
00423          } else if((c == '\t'))
00424          {
00425                 ;
00426          } else if((c == '\n' || c == ' ') && t)
00427          {
00428                 ;
00429          }
00430 
00431          else if(c == '\n' && i != 0)
00432          {
00433 
00434                 value[i] = '\0';
00435                 //printf("type:|%s| value:|%s|\n", type, value);
00436                 str = type;
00437                 if(str == "vendor_id")
00438                 {
00439                  cpu->setVendor(value);
00440                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00441                  p->setAttribute("name", "vendor-id");
00442                  p->setAttribute("value", value);
00443                 } else if(str == "model name")
00444                 {
00445                  cpu->setModel(value);
00446                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00447                  p->setAttribute("name", "model-name");
00448                  p->setAttribute("value", value);
00449                 } else if(str == "cpu MHz")
00450                 {
00451                  //TODO: not DOUBLE
00452                  Real clock;
00453 
00454                  sscanf(value, "%lf", &clock);
00455                  cpu->setClock(clock);
00456                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00457                  p->setAttribute("name", "cpu-mhz");
00458                  p->setAttribute("value", value);
00459                 } else if(str == "cache size")
00460                 {
00461                  u32 cache;
00462 
00463                  sscanf(value, "%d", &cache);
00464                  cpu->setCache(cache);
00465                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00466                  p->setAttribute("name", "cache-size");
00467                  p->setAttribute("value", value);
00468                 } else if(str == "bogomips")
00469                 {
00470                  //TODO: not DOUBLE
00471                  Real bogomips;
00472 
00473                  sscanf(value, "%lf", &bogomips);
00474                  cpu->setBogomips(bogomips);
00475                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00476                  p->setAttribute("name", "bogomips");
00477                  p->setAttribute("value", value);
00478                 } else if(str == "flags")
00479                 {
00480                  cpu->setFlags(value);
00481                  OutputNode::Pointer p = cpu->createChildNode("param", OutputNode::INFORMATION);
00482                  p->setAttribute("name", "flags");
00483                  p->setAttribute("value", value);
00484                 } else if(str == "processor")
00485                 {
00486 
00487                  cpu = new CPU("CPU", OutputNode::INFORMATION);
00488                  cpu->setAttribute("id", value);
00489 
00490                  mCPUs->add("CPU-" + std::string(value), cpu);
00491 
00492                  OutputNode::Pointer oCpu;
00493                  oCpu.reference(cpu.getPtr());
00494                  cpus->addChildNode(oCpu);
00495 
00496                 }
00497 
00498                 i = 0;
00499 
00500                 t = true;
00501          } else
00502          {
00503                 if(t)
00504                 {
00505                  type[i++] = c;
00506                 } else
00507                 {
00508                  value[i++] = c;
00509                 }
00510 
00511          }
00512 
00513         }
00514         FileSystemManager::getInstance()->closeFile(f);
00515 
00516   }
00517 
00518  /*----------------------------------------------------------------------*/
00519 
00520   void HostInfo::refreshGPUs(OutputNode::Pointer & gpus)
00521   {
00522         GPU::Pointer gpu;
00523         gpu = new GPU("GPU", OutputNode::INFORMATION);
00524         mGPUs->add("GPU", gpu);
00525 
00526         OutputNode::Pointer oGpu;
00527         oGpu.reference(gpu.getPtr());
00528         gpus->addChildNode(oGpu);
00529 
00530   }
00531 
00532  /*----------------------------------------------------------------------*/
00533 
00534 }