Main Page | Namespace List | Class Hierarchy | Compound List | File List | Namespace Members | Compound Members | File Members

platfDepend.cxx

Go to the documentation of this file.
00001 /**************************************************************************
00002 ***    
00003 *** Copyright (c) 1995-2000 Regents of the University of California,
00004 ***               Andrew E. Caldwell, Andrew B. Kahng and Igor L. Markov
00005 *** Copyright (c) 2000-2004 Regents of the University of Michigan,
00006 ***               Saurabh N. Adya, Jarrod A. Roy and Igor L. Markov
00007 ***
00008 ***  Contact author(s): abk@cs.ucsd.edu, imarkov@umich.edu
00009 ***  Original Affiliation:   UCLA, Computer Science Department,
00010 ***                          Los Angeles, CA 90095-1596 USA
00011 ***
00012 ***  Permission is hereby granted, free of charge, to any person obtaining 
00013 ***  a copy of this software and associated documentation files (the
00014 ***  "Software"), to deal in the Software without restriction, including
00015 ***  without limitation 
00016 ***  the rights to use, copy, modify, merge, publish, distribute, sublicense, 
00017 ***  and/or sell copies of the Software, and to permit persons to whom the 
00018 ***  Software is furnished to do so, subject to the following conditions:
00019 ***
00020 ***  The above copyright notice and this permission notice shall be included
00021 ***  in all copies or substantial portions of the Software.
00022 ***
00023 *** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
00024 *** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00025 *** OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
00026 *** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
00027 *** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
00028 *** OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
00029 *** THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00030 ***
00031 ***
00032 ***************************************************************************/
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 // August   22, 1997   created   by Igor Markov  VLSI CAD UCLA ABKGROUP
00044 // November 30, 1997   additions by Max Moroz,   VLSI CAD UCLA ABKGROUP
00045 
00046 // note: not thread-safe
00047 
00048 // This file to be included into all projects in the group
00049 // it contains platform-specific code portability of which relies
00050 // on symbols defined by compilers
00051 
00052 // 970825 mro made corrections to conditional compilation in ctors for
00053 //            Platform and User:
00054 //            i)   _MSC_VER not __MSC_VER (starts with single underscore)
00055 //            ii)  allocated more space for _infoLines
00056 //            iii) changed nested #ifdefs to #if ... #elif ... #else
00057 // 970923 ilm added abk_dump_stack()
00058 // 971130 ilm added Max Moroz code for memory estimate and reworked
00059 //            class MemUsage()
00060 // 980822 mm  corrected MemUsage() to work with Solaris 2.6
00061 
00062 #ifdef _MSC_VER
00063  #pragma warning(disable:4786)
00064 #define _X86_
00065 #include <cstdarg>
00066 #include <windef.h>
00067 #include <winbase.h>
00068 //#include <winreg.h>
00069 #include <direct.h>
00070 
00071 #include <cstdio>
00072 #include <cstdlib>
00073 #include <string>
00074 #else
00075 #include <stdio.h>
00076 #include <stdlib.h>
00077 #include <string.h>
00078 #endif 
00079 
00080 #include "infolines.h"
00081 #include "abktypes.h"
00082 #include "abkassert.h"
00083 
00084 #if defined(sun) || defined(__SUNPRO_CC)
00085  #include <sys/systeminfo.h>
00086 #endif
00087 
00088 #ifdef linux
00089  #include <sys/utsname.h>
00090 #endif     
00091 
00092 #if defined(linux) || defined(sun) || defined(__SUNPRO_CC)
00093  #include <unistd.h>
00094  #include <pwd.h>
00095  #include <sys/stat.h>
00096 #endif
00097 
00098 /* ======================== IMPLEMENTATIONS ======================== */
00099 
00100 void abk_dump_stack()
00101 {
00102     return;
00103 #if defined(linux) || defined(sun) || defined(__SUNPRO_CC)
00104     printf("\n  --- ABK GROUP DELIBERATE STACK DUMP  ----------- \n\n");
00105     fflush(stdout);
00106     char s[160];
00107     unsigned ProcId=getpid();
00108  #if defined(linux)
00109     sprintf(s, "/bin/echo \"bt   \nquit   \\n\" | "
00110                "gdb -q /proc/%d/exe %d", ProcId,ProcId);
00111  #else
00112     sprintf(s, "/bin/echo \"where\\ndetach \\n\" | dbx - %d", ProcId);
00113  #endif
00114     system(s);
00115     printf("  ------------------ END STACK DUMP -------------- \n");
00116     fflush(stdout);
00117 #else
00118 // fprintf(stderr," abk_dump_stack(): Can't dump stack on this platform\n");
00119 // fflush(stderr);
00120 #endif
00121     return;
00122 }
00123 
00124 void abk_call_debugger()
00125 {
00126 #if defined(linux) || defined(sun) || defined(__SUNPRO_CC)
00127     unsigned ProcId=getpid();
00128     printf("\n  --- ATTACHING DEBUGGER to process %d ", ProcId);
00129     printf(" (an ABKGROUP utility) --- \n\n");
00130     fflush(stdout);
00131     char s[160];
00132  #if defined(linux)
00133     sprintf(s, "gdb -q /proc/%d/exe %d", ProcId,ProcId);
00134  #else // must be Solaris
00135     sprintf(s, "dbx - %d", ProcId);
00136  #endif
00137     system(s);
00138     printf("  ------------------ CONTINUING -------------- \n");
00139     fflush(stdout);
00140 #else
00141  fprintf(stderr," abk_call_debugger(): Can't call debugger on this platform\n");
00142  fflush(stderr);
00143 #endif
00144     return;
00145 }
00146 
00147 double getPeakMemoryUsage()
00148 {
00149 
00150 #if ! (defined(sun) || defined(linux) || defined(__SUNPRO_CC))
00151   return -1;
00152 #endif
00153 
00154 #if defined(sun) || defined(__SUNPRO_CC)
00155   char procFileName[20];
00156   unsigned pid=getpid();
00157   sprintf(procFileName,"/proc/%d/as",pid);
00158   struct stat buf;
00159   if (stat(procFileName,&buf))  // no such file on Solaris 2.5 and earlier
00160   {                             // so we stat another file now
00161     char procFileNameOld[20];
00162     sprintf(procFileNameOld,"/proc/%d",pid);
00163     if (stat(procFileNameOld,&buf)) 
00164         return -1.0;
00165   }
00166   return (1.0/(1024*1024)) * buf.st_size;
00167 #elif defined(linux)
00168   char buf[1000];
00169   sprintf(buf,"/proc/%d/stat", static_cast<unsigned>(getpid()));
00170   ifstream ifs(buf);
00171   for(unsigned k=0; k!=23; k++) ifs >> buf;
00172       //  cout << k << ": " << buf << endl; }
00173   return (1.0/(1024*1024)) * atoi(buf);
00174 #else
00175   return -1;
00176 #endif
00177 }
00178 
00179 static double getMemoryUsageEstimate();
00180 
00181 MemUsage::MemUsage()
00182 {
00183   _peak=getPeakMemoryUsage();
00184   #if (defined(sun) || defined(__SUNPRO_CC) || defined(linux))
00185     _estimate=_peak;
00186     return ;
00187   #endif
00188   _estimate=getMemoryUsageEstimate();
00189 }
00190 
00191 void MemChange::resetMark()
00192 {
00193   _memUsageMark=getMemoryUsageEstimate();
00194 }
00195 
00196 MemChange::MemChange()
00197 {
00198   resetMark();
00199 }
00200 
00201 MemChange::operator double() const
00202 {
00203 #if defined(sun) || defined(linux) || defined(__SUNPRO_CC)
00204   return getPeakMemoryUsage()-_memUsageMark;
00205 #else
00206   return -1.0;
00207 #endif
00208 }
00209 
00210 Platform::Platform()
00211 {
00212 #if defined(sun) || defined(__SUNPRO_CC)
00213   Str31 sys, rel, arch, platf;
00214   sysinfo(SI_SYSNAME, sys, 31);
00215   sysinfo(SI_RELEASE, rel, 31);
00216   sysinfo(SI_ARCHITECTURE,arch, 31);
00217   sysinfo(SI_PLATFORM,platf, 31);
00218   _infoLine= new char[strlen(sys)+strlen(rel)+strlen(arch)+strlen(platf)+30];
00219   sprintf(_infoLine,"# Platform     : %s %s %s %s \n",sys,rel,arch,platf);
00220 #elif defined(linux)
00221   struct utsname buf;
00222   uname(&buf);
00223   _infoLine= new char[strlen(buf.sysname)+strlen(buf.release)
00224                      +strlen(buf.version)+strlen(buf.machine)+30];
00225   sprintf(_infoLine,"# Platform     : %s %s %s %s \n",buf.sysname,buf.release,
00226                                                       buf.version,buf.machine);
00227 #elif defined(_MSC_VER)
00228   _infoLine= new char[40];
00229   strcpy(_infoLine, "# Platform     : MS Windows \n");
00230 #else
00231   _infoLine= new char[40];
00232   strcpy(_infoLine, "# Platform     : unknown \n");
00233 #endif
00234 }
00235 
00236 #if !defined(sun) && !defined(linux)
00237 extern  int gethostname(char*, int);
00238 #endif
00239 
00240 User::User()
00241 {
00242 
00243 //#if defined(linux) || defined(sun) || defined(__SUNPRO_CC)
00244 #if defined(linux) 
00245   char host[100]; 
00246   gethostname(host,31);
00247   struct passwd *pwr=getpwuid(getuid());
00248   if (pwr==NULL)
00249   {
00250     _infoLine= new char[40];
00251      strcpy(_infoLine, "# User         : unknown \n");
00252      return;
00253   }
00254 
00255   _infoLine= new char[strlen(pwr->pw_name)+strlen(pwr->pw_gecos)+130];
00256   sprintf(_infoLine,"# User         : %s@%s (%s) \n",
00257                       pwr->pw_name,host,pwr->pw_gecos);
00258 #elif defined(_MSC_VER)
00259   _infoLine= new char[40];
00260   strcpy(_infoLine, "# User         : unknown \n");
00261 #else
00262   _infoLine= new char[40];
00263   strcpy(_infoLine, "# User         : unknown \n");
00264 #endif
00265 }
00266 
00267 // code by Max Moroz
00268 
00269 const int kMegaByte=1024*1024;
00270 const int kSmallChunks=1000;
00271 const int kMaxAllocs=20000;
00272 const double MemUsageEps=3;
00273 
00274 // everything in bytes
00275 
00276 inline int memused()
00277 {
00278 // cout << " Peak memory " << getPeakMemoryUsage() << endl;
00279    return static_cast<int>(getPeakMemoryUsage()*kMegaByte);
00280 }
00281 
00282 double getMemoryUsageEstimate()
00283 {
00284 #if ! (defined(linux) || defined(sun) || defined(__SUNPRO_CC))
00285         return -1;
00286 #endif
00287         static int prevMem=0;
00288         static int extra;
00289         static int fail=0;
00290 
00291         if (fail) return -1;
00292 
00293 //      new_handler oldHndl;
00294 //      oldHndl=set_new_handler(mH);
00295 
00296         void* ptr[kMaxAllocs];
00297         int numAllocs=0;
00298 
00299         int last=memused();
00300 //       cout << "Memused : " << last << endl;
00301         if (last<=0) return -1;
00302 //      cerr<<"memused()="<<memused()<<endl;
00303         int chunk=8192; // system allocates 8K chunks
00304         int allocated=0;
00305         int countSmallChunks=kSmallChunks;
00306         // if we allocate <8K, we'd get memused()+=8K, and allocated<8K - error
00307         while (1)
00308         {
00309 //              abkfatal(numAllocs<kMaxAllocs, "too many allocs");
00310                 if (numAllocs>=kMaxAllocs) 
00311                 {   
00312                    abkwarn(0,"too many allocs (may be okay for 64-bit builds)");
00313                    // FIFO destruction
00314                    for (int i=0; i!=numAllocs; ++i) free(ptr[i]);
00315                     return -1.0;     
00316                 }
00317 //              cerr<<"old: "<<memused()<<"; allocating "<<chunk<<"; now: ";
00318                 if (!(ptr[numAllocs++]=malloc(chunk)))
00319                 {
00320                         fail=1;
00321                         return -1;
00322                 }
00323 //              cerr<<memused()<<endl;
00324                 allocated+=chunk;
00325                 if (memused()>last+MemUsageEps)
00326                         break;
00327                 if (chunk<=kMegaByte && !countSmallChunks--)
00328                 {
00329                                 chunk*=2;
00330                                 countSmallChunks=kSmallChunks;
00331                 }
00332         }
00333 
00334 //     int result=memused()-allocated-prevMem;
00335 
00336 /* LIFO destruction
00337         while (numAllocs) free(ptr[--numAllocs]); */
00338 
00339         // FIFO destruction
00340         for (int i=0; i!=numAllocs; ++i) free(ptr[i]);
00341 
00342         extra=memused()-last;
00343 // handle extra correctly:
00344 // in some cases we need to add its prev value to current,
00345 // in some just store the new value
00346 
00347         prevMem=memused()-allocated;
00348 //      set_new_handler(oldHndl);
00349         return prevMem/double(kMegaByte);
00350 }
00351 
00352 UserHomeDir::UserHomeDir()
00353 {
00354 #if defined(sun) || defined(linux)
00355   struct passwd *pwrec;
00356   pwrec=getpwuid(getuid()); 
00357   _infoLine=strdup(pwrec->pw_dir);
00358 #elif defined(_MSC_VER)
00359   char *homedr=getenv("HOMEDRIVE");
00360   char *homepath=getenv("HOMEPATH");
00361   char *pathbuf=new char[_MAX_PATH];
00362   if (homedr==NULL || homepath==NULL)
00363       strcpy(pathbuf, "c:\\users\\default");
00364   else
00365       _makepath(pathbuf,homedr,homepath,NULL,NULL);
00366   int len=strlen(pathbuf);
00367   if (pathbuf[len-1]=='\\') pathbuf[len-1]='\0';
00368   _infoLine=strdup(pathbuf);
00369   delete [] pathbuf;
00370 #endif
00371 }
00372 
00373 ExecLocation::ExecLocation()
00374 { 
00375   char buf[1000]="";
00376 #ifdef linux
00377   readlink("/proc/self/exe", buf, 1000); 
00378   int pos=strlen(buf)-1;
00379   for (;pos>=0;pos--)
00380     {
00381     if (buf[pos]=='/')
00382       {
00383       buf[pos]='\0';
00384       break;
00385       }
00386     }
00387 #endif
00388 
00389 #if defined(sun) || defined(__SUNPRO_CC)
00390   pid_t pid=getpid();
00391   char tempfname[100]="";
00392   sprintf(tempfname,"/tmp/atempf%d",static_cast<int>(pid));
00393   sprintf(buf,"/usr/proc/bin/ptree %d | tail -4 > %s",
00394                                   static_cast<int>(pid),tempfname);
00395   system(buf);
00396   { ifstream ifs(tempfname); ifs >> buf; ifs >> buf;}
00397   unlink(tempfname);
00398   if (buf[0]!='/')
00399   {
00400     if (strrchr(buf,'/')==NULL) 
00401     { getcwd(buf,1000); _infoLine=strdup(buf); return; }
00402     else
00403     { 
00404       char buf1[500]="",buf2[1000]="";
00405       getcwd(buf1,500);
00406       strncpy(buf2,buf,500);
00407       sprintf(buf,"%s/%s",buf1,buf2);
00408     }
00409   }
00410   char *lastDelim=strrchr(buf,'/');
00411   if (lastDelim==NULL) sprintf(buf,"Cannot find");
00412   else                 *lastDelim='\0';
00413 #elif defined(_MSC_VER)
00414   ::GetModuleFileName(NULL,buf,995);
00415   char drv[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
00416   _splitpath(buf,drv,dir,fname,ext);
00417   _makepath(buf,drv,dir,"","");
00418   int len=strlen(buf);
00419   if (buf[len-1]=='\\') buf[len-1]='\0';
00420 #endif
00421 
00422   _infoLine=strdup(buf);
00423 }

Generated on Mon Apr 25 01:09:24 2005 for Parquete by doxygen 1.3.2