Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

utilities.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2008 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: utilities.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.111 $      $Date: 2008/06/02 08:03:09 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * General utility routines and definitions.
00020  *
00021  ***************************************************************************/
00022 
00023 #include <string.h>
00024 #include <ctype.h>
00025 #include <math.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 
00029 #if defined(_MSC_VER)
00030 #include <windows.h>
00031 #include <conio.h>
00032 #else
00033 #include <unistd.h>
00034 #include <sys/time.h>
00035 #include <errno.h>
00036 
00037 #if defined(ARCH_AIX4)
00038 #include <strings.h>
00039 #endif
00040 
00041 #if defined(ARCH_IRIX5) || defined(ARCH_IRIX6) || defined(ARCH_IRIX6_64)
00042 #include <bstring.h>
00043 #endif
00044 
00045 #if defined(ARCH_HPUX9) || defined(ARCH_HPUX10) || defined(ARCH_HPUX11)
00046 #include <time.h>
00047 #endif // HPUX
00048 #endif // _MSC_VER
00049 
00050 #if defined(__APPLE__)
00051 #include <sys/sysctl.h>
00052 #endif
00053 
00054 #include "utilities.h"
00055 #include "config.h"  // for DEF_VMDTMPDIR
00056 
00057 // given an argc, argv pair, take all the arguments from the Nth one on
00058 // and combine them into a single string with spaces separating words.  This
00059 // allocates space for the string, which must be freed by the user.
00060 char *combine_arguments(int argc, const char **argv, int n) {
00061   char *newstr = NULL;
00062 
00063   if(argc > 0 && n < argc && n >= 0) {
00064     int i, sl = 0;
00065     // find out the length of the words we must combine
00066     for(i=n; i < argc; i++)
00067       sl += strlen(argv[i]);
00068 
00069     // combine the words together
00070     if(sl) {
00071       newstr = new char[sl + 8 + argc - n];     // extra buffer added
00072       *newstr = '\0';
00073       for(i=n; i < argc; i++) {
00074         if(i != n)
00075           strcat(newstr," ");
00076         strcat(newstr, argv[i]);
00077       }
00078     }
00079   }
00080 
00081   // return the string, or NULL if a problem occurred
00082   return newstr;
00083 }
00084 
00085 
00086 // duplicate a string using c++ new call
00087 char *stringdup(const char *s) {
00088   char *rs;
00089 
00090   if(!s)
00091     return NULL;
00092 
00093   rs = new char[strlen(s) + 1];
00094   strcpy(rs,s);
00095 
00096   return rs;
00097 }
00098 
00099 
00100 // convert a string to upper case
00101 char *stringtoupper(char *s) {
00102   int i;
00103   int sz = strlen(s);
00104 
00105   if (s != NULL) {
00106     for(i=0; i<sz; i++)
00107       s[i] = toupper(s[i]);
00108   }
00109 
00110   return s;
00111 }
00112 
00113 void stripslashes(char *str) {
00114   while (strlen(str) > 0 && str[strlen(str) - 1] == '/') {
00115     str[strlen(str) - 1] = '\0';
00116   }
00117 }
00118 
00119 // do upper-case comparison
00120 int strupcmp(const char *a, const char *b) {
00121   char *ua, *ub;
00122   int retval;
00123 
00124   ua = stringtoupper(stringdup(a));
00125   ub = stringtoupper(stringdup(b));
00126 
00127   retval = strcmp(ua,ub);
00128 
00129   delete [] ub;
00130   delete [] ua;
00131 
00132   return retval;
00133 }
00134 
00135 
00136 // do upper-case comparison, up to n characters
00137 int strupncmp(const char *a, const char *b, int n) {
00138 #if defined(ARCH_AIX3) || defined(ARCH_AIX4) || defined(_MSC_VER)
00139    while (n-- > 0) {
00140       if (toupper(*a) != toupper(*b)) {
00141          return toupper(*b) - toupper(*a);
00142       }
00143       if (*a == 0) return 0;
00144       a++; b++;
00145    }
00146    return 0;
00147 #else
00148    return strncasecmp(a, b, n);
00149 #endif
00150 }
00151 
00152 
00153 // break a file name up into path + name, returning both in the specified
00154 //      character pointers.  This creates storage for the new strings
00155 //      by allocating space for them.
00156 void breakup_filename(const char *full, char **path, char **name) {
00157   const char *namestrt;
00158   int pathlen;
00159 
00160   if(full == NULL) {
00161     *path = *name = NULL;
00162     return;
00163   } else if (strlen(full) == 0) {
00164     *path = new char[1];
00165     *name = new char[1];
00166     (*path)[0] = (*name)[0] = '\0';
00167     return;
00168   }
00169 
00170   // find start of final file name
00171   if((namestrt = strrchr(full,'/')) != NULL && strlen(namestrt) > 0) {
00172     namestrt++;
00173   } else {
00174     namestrt = full;
00175   }
00176 
00177   // make a copy of the name
00178   *name = stringdup(namestrt);
00179 
00180   // make a copy of the path
00181   pathlen = strlen(full) - strlen(*name);
00182   *path = new char[pathlen + 1];
00183   strncpy(*path,full,pathlen);
00184   (*path)[pathlen] = '\0';
00185 } 
00186 
00187 // break a configuration line up into tokens.
00188 char *str_tokenize(const char *newcmd, int *argc, char *argv[]) {
00189   char *cmd; 
00190   const char *cmdstart;
00191   cmdstart = newcmd;
00192 
00193   // guarantee that the command string we return begins on the first
00194   // character returned by strtok(), otherwise the subsequent delete[]
00195   // calls will reference invalid memory blocks
00196   while (cmdstart != NULL &&
00197          (*cmdstart == ' '  ||
00198           *cmdstart == ','  ||
00199           *cmdstart == ';'  ||
00200           *cmdstart == '\t' ||
00201           *cmdstart == '\n')) {
00202     cmdstart++; // advance pointer to first command character
00203   } 
00204 
00205   cmd = stringdup(cmdstart);
00206   *argc = 0;
00207 
00208   // initialize tokenizing calls
00209   argv[*argc] = strtok(cmd, " ,;\t\n");
00210 
00211   // loop through words until end-of-string, or comment character, found
00212   while(argv[*argc] != NULL) {
00213     // see if the token starts with '#'
00214     if(argv[*argc][0] == '#') {
00215       break;                    // don't process any further tokens
00216     } else {
00217       (*argc)++;                // another token in list
00218     }
00219     
00220     // scan for next token
00221     argv[*argc] = strtok(NULL," ,;\t\n");
00222   }
00223 
00224   return (*argc > 0 ? argv[0] : (char *) NULL);
00225 }
00226 
00227 
00228 // get the time of day from the system clock, and store it (in seconds)
00229 double time_of_day(void) {
00230 #if defined(_MSC_VER)
00231   double t;
00232  
00233   t = GetTickCount(); 
00234   t = t / 1000.0;
00235 
00236   return t;
00237 #else
00238   struct timeval tm;
00239   struct timezone tz;
00240 
00241   gettimeofday(&tm, &tz);
00242   return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
00243 #endif
00244 }
00245 
00246 
00247 #if defined(_MSC_VER)
00248 typedef struct {
00249   DWORD starttime;
00250   DWORD endtime;
00251 } vmd_timer;
00252 
00253 void vmd_timer_start(vmd_timerhandle v) {
00254   vmd_timer * t = (vmd_timer *) v;
00255   t->starttime = GetTickCount();
00256 }
00257 
00258 void vmd_timer_stop(vmd_timerhandle v) {
00259   vmd_timer * t = (vmd_timer *) v;
00260   t->endtime = GetTickCount();
00261 }
00262 
00263 double vmd_timer_time(vmd_timerhandle v) {
00264   vmd_timer * t = (vmd_timer *) v;
00265   double ttime;
00266 
00267   ttime = ((double) (t->endtime - t->starttime)) / 1000.0;
00268 
00269   return ttime;
00270 }
00271 
00272 #else
00273 
00274 // Unix with gettimeofday() 
00275 typedef struct {
00276   struct timeval starttime, endtime;
00277   struct timezone tz;
00278 } vmd_timer;
00279 
00280 void vmd_timer_start(vmd_timerhandle v) {
00281   vmd_timer * t = (vmd_timer *) v;
00282   gettimeofday(&t->starttime, &t->tz);
00283 }
00284  
00285 void vmd_timer_stop(vmd_timerhandle v) {
00286   vmd_timer * t = (vmd_timer *) v;
00287   gettimeofday(&t->endtime, &t->tz);
00288 }
00289  
00290 double vmd_timer_time(vmd_timerhandle v) {
00291   vmd_timer * t = (vmd_timer *) v;
00292   double ttime;
00293   ttime = ((double) (t->endtime.tv_sec - t->starttime.tv_sec)) +
00294           ((double) (t->endtime.tv_usec - t->starttime.tv_usec)) / 1000000.0;
00295   return ttime;
00296 } 
00297 #endif
00298 
00299 // system independent routines to create and destroy timers
00300 vmd_timerhandle vmd_timer_create(void) {
00301   vmd_timer * t;
00302   t = (vmd_timer *) malloc(sizeof(vmd_timer));
00303   memset(t, 0, sizeof(vmd_timer));
00304   return t;
00305 }
00306 
00307 void vmd_timer_destroy(vmd_timerhandle v) {
00308   free(v);
00309 }
00310 
00311 double vmd_timer_timenow(vmd_timerhandle v) {
00312   vmd_timer_stop(v);
00313   return vmd_timer_time(v);
00314 }
00315 
00317 msgtimer * msg_timer_create(double updatetime) {
00318   msgtimer *mt;
00319   mt = (msgtimer *) malloc(sizeof(msgtimer)); 
00320   if (mt != NULL) {
00321     mt->timer = vmd_timer_create();    
00322     mt->updatetime = updatetime;
00323     vmd_timer_start(mt->timer);
00324   }
00325   return mt;
00326 }
00327 
00329 int msg_timer_timeout(msgtimer *mt) {
00330   double elapsed = vmd_timer_timenow(mt->timer);
00331   if (elapsed > mt->updatetime) {
00332     // reset the clock and return true that our timer expired
00333     vmd_timer_start(mt->timer);
00334     return 1;
00335   } else if (elapsed < 0) {
00336     // time went backwards, best reset our clock!
00337     vmd_timer_start(mt->timer);
00338   }
00339   return 0;
00340 }
00341 
00343 void msg_timer_destroy(msgtimer * mt) {
00344   vmd_timer_destroy(mt->timer);
00345   free(mt);
00346 }
00347 
00348 int vmd_check_stdin(void) {
00349 #if defined(_MSC_VER)
00350   if (_kbhit() != 0)
00351     return TRUE;
00352   else
00353     return FALSE;
00354 #else
00355   fd_set readvec;
00356   struct timeval timeout;
00357   int ret, stdin_fd;
00358 
00359   timeout.tv_sec = 0;
00360   timeout.tv_usec = 0;
00361   stdin_fd = 0;
00362   FD_ZERO(&readvec);
00363   FD_SET(stdin_fd, &readvec);
00364 
00365 #if !defined(ARCH_AIX3)
00366   ret = select(16, &readvec, NULL, NULL, &timeout);
00367 #else
00368   ret = select(16, (int *)(&readvec), NULL, NULL, &timeout);
00369 #endif
00370  
00371   if (ret == -1) {  // got an error
00372     if (errno != EINTR)  // XXX: this is probably too lowlevel to be converted to Inform.h
00373       printf("select() error while attempting to read text input.\n");
00374     return FALSE;
00375   } else if (ret == 0) {
00376     return FALSE;  // select timed out
00377   }
00378   return TRUE;
00379 #endif
00380 }
00381 
00382 
00383 // return the username of the currently logged-on user
00384 char *vmd_username(void) {
00385 #if defined(_MSC_VER)
00386   char username[1024];
00387   unsigned long size = 1023;
00388 
00389   if (GetUserName((char *) &username, &size)) {
00390     return stringdup(username);
00391   }
00392   else { 
00393     return stringdup("Windows User");
00394   }
00395 #else
00396 #if defined(ARCH_FREEBSD) || defined(ARCH_MACOSX) || defined(ARCH_MACOSXX86) || defined(ARCH_MACOSXX86_64) || defined(ARCH_LINUX) || defined(ARCH_LINUXALPHA) || defined(ARCH_LINUXAMD64) || defined(ARCH_LINUXIA64) || defined(ARCH_LINUXPPC) || defined(ARCH_LINUXPPC64)
00397   return stringdup(getlogin());
00398 #else
00399   return stringdup(cuserid(NULL));
00400 #endif 
00401 #endif
00402 }
00403 
00404 int vmd_getuid(void) {
00405 #if defined(_MSC_VER)
00406   return 0;
00407 #else
00408   return getuid(); 
00409 #endif
00410 }
00411 
00412 // take three 3-vectors and compute x2 cross x3; with the results
00413 // in x1.  x1 must point to different memory than x2 or x3
00414 // This returns a pointer to x1
00415 float * cross_prod(float *x1, const float *x2, const float *x3)
00416 {
00417   x1[0] =  x2[1]*x3[2] - x3[1]*x2[2];
00418   x1[1] = -x2[0]*x3[2] + x3[0]*x2[2];
00419   x1[2] =  x2[0]*x3[1] - x3[0]*x2[1];
00420   return x1;
00421 }
00422 
00423 // normalize a vector, and return a pointer to it
00424 // Warning:  it changes the value of the vector!!
00425 float * vec_normalize(float *vect) {
00426   float len = vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2];
00427 
00428   // prevent division by zero
00429   if (len > 0) {
00430     float rescale = 1.0f / sqrtf(len);
00431     vect[0] *= rescale;
00432     vect[1] *= rescale;
00433     vect[2] *= rescale;
00434   }
00435 
00436   return vect;
00437 }
00438 
00439 
00440 // find and return the norm of a 3-vector
00441 float norm(const float *vect) {
00442   return sqrtf(vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2]);
00443 }
00444 
00445 
00446 // determine if a triangle is degenerate or not
00447 int tri_degenerate(const float * v0, const float * v1, const float * v2) {
00448   float s1[3], s2[3], s1_length, s2_length;
00449 
00450   /*
00451    various rendering packages have amusingly different ideas about what
00452    constitutes a degenerate triangle.  -1 and 1 work well.  numbers
00453    below 0.999 and -0.999 show up in OpenGL
00454    numbers as low as 0.98 have worked in POVRay with certain models while
00455    numbers as high as 0.999999 have produced massive holes in other
00456    models
00457          -matt 11/13/96
00458   */
00459 
00460   /**************************************************************/
00461   /*    turn the triangle into 2 normalized vectors.            */
00462   /*    If the dot product is 1 or -1 then                      */
00463   /*   the triangle is degenerate                               */
00464   /**************************************************************/
00465   s1[0] = v0[0] - v1[0];
00466   s1[1] = v0[1] - v1[1];
00467   s1[2] = v0[2] - v1[2];
00468 
00469   s2[0] = v0[0] - v2[0];
00470   s2[1] = v0[1] - v2[1];
00471   s2[2] = v0[2] - v2[2];
00472 
00473   s1_length = sqrtf(s1[0]*s1[0] + s1[1]*s1[1] + s1[2]*s1[2]);
00474   s2_length = sqrtf(s2[0]*s2[0] + s2[1]*s2[1] + s2[2]*s2[2]);
00475 
00476   /**************************************************************/
00477   /*                   invert to avoid divides:                 */
00478   /*                         1.0/v1_length * 1.0/v2_length      */
00479   /**************************************************************/
00480 
00481   s2_length = 1.0f / (s1_length*s2_length);
00482   s1_length = s2_length * (s1[0]*s2[0] + s1[1]*s2[1] + s1[2]*s2[2]);
00483 
00484   // and add it to the list if it's not degenerate
00485   if ((s1_length >= 1.0 ) || (s1_length <= -1.0)) 
00486     return 1;
00487   else
00488     return 0;
00489 }
00490 
00491 
00492 // compute the angle (in degrees 0 to 180 ) between two vectors a & b
00493 float angle(const float *a, const float *b) {
00494   float ab[3];
00495   cross_prod(ab, a, b);
00496   float psin = sqrtf(dot_prod(ab, ab));
00497   float pcos = dot_prod(a, b);
00498   return 57.2958f * (float) atan2(psin, pcos);
00499 }
00500 
00501 
00502 // Compute the dihedral angle for the given atoms, returning a value between
00503 // -180 and 180.
00504 // faster, cleaner implementation based on atan2
00505 float dihedral(const float *a1,const float *a2,const float *a3,const float *a4)
00506 {
00507   float r1[3], r2[3], r3[3], n1[3], n2[3];
00508   vec_sub(r1, a2, a1);
00509   vec_sub(r2, a3, a2);
00510   vec_sub(r3, a4, a3);
00511   
00512   cross_prod(n1, r1, r2);
00513   cross_prod(n2, r2, r3);
00514   
00515   float psin = dot_prod(n1, r3) * sqrtf(dot_prod(r2, r2));
00516   float pcos = dot_prod(n1, n2);
00517 
00518   // atan2f would be faster, but we'll have to workaround the lack
00519   // of existence on some platforms.
00520   return 57.2958f * (float) atan2(psin, pcos);
00521 }
00522  
00523 // compute the distance between points a & b
00524 float distance(const float *a, const float *b) {
00525   return sqrtf(distance2(a,b));
00526 }
00527 
00528 char *vmd_tempfile(const char *s) {
00529   char *envtxt, *TempDir;
00530 
00531   if((envtxt = getenv("VMDTMPDIR")) != NULL) {
00532     TempDir = stringdup(envtxt);
00533   } else {
00534 #if defined(_MSC_VER)
00535     if ((envtxt = getenv("TMP")) != NULL) {
00536       TempDir = stringdup(envtxt);
00537     }
00538     else if ((envtxt = getenv("TEMP")) != NULL) {
00539       TempDir = stringdup(envtxt);
00540     }
00541     else {
00542       TempDir = stringdup(DEF_VMDTMPDIR);
00543     }
00544 #else
00545     TempDir = stringdup(DEF_VMDTMPDIR);
00546 #endif
00547   }
00548   stripslashes(TempDir); // strip out ending '/' chars.
00549 
00550   char *tmpfilebuf = new char[1024];
00551  
00552   // copy in temp string
00553   strcpy(tmpfilebuf, TempDir);
00554  
00555 #if defined(_MSC_VER)
00556   strcat(tmpfilebuf, "\\");
00557   strncat(tmpfilebuf, s, 1022 - strlen(TempDir));
00558 #else
00559   strcat(tmpfilebuf, "/");
00560   strncat(tmpfilebuf, s, 1022 - strlen(TempDir));
00561 #endif
00562  
00563   tmpfilebuf[1023] = '\0';
00564  
00565   delete [] TempDir;
00566 
00567   // return converted string
00568   return tmpfilebuf;
00569 }
00570 
00571 
00572 int vmd_delete_file(const char * path) {
00573 #if defined(_MSC_VER)
00574   if (DeleteFile(path) == 0) 
00575     return -1;
00576   else 
00577     return 0;  
00578 #else
00579   return unlink(path);
00580 #endif
00581 }
00582 
00583 void vmd_sleep(int secs) {
00584 #if defined(_MSC_VER)
00585   Sleep(secs * 1000);
00586 #else 
00587   sleep(secs);
00588 #endif
00589 }
00590 
00591 void vmd_msleep(int msecs) {
00592 #if defined(_MSC_VER)
00593   Sleep(msecs);
00594 #else 
00595   struct timeval timeout;
00596   timeout.tv_sec = 0;
00597   timeout.tv_usec = 1000 * msecs;
00598   select(0, NULL, NULL, NULL, &timeout);
00599 #endif // _MSC_VER
00600 }
00601 
00602 int vmd_system(const char* cmd) {
00603    return system(cmd);
00604 }
00605 
00606 
00610 long vmd_random(void) {
00611 #ifdef _MSC_VER
00612   return rand();
00613 #else
00614   return random();
00615 #endif
00616 }
00617 
00618 void vmd_srandom(unsigned int seed) {
00619 #ifdef _MSC_VER
00620   srand(seed);
00621 #else
00622   srandom(seed);
00623 #endif
00624 }
00625 
00628 float vmd_random_gaussian() {
00629   static bool cache = false;
00630   static float cached_value;
00631   const float RAND_FACTOR = 2.f/VMD_RAND_MAX;
00632   float r, s, w;
00633   
00634   if (cache) {
00635     cache = false;
00636     return cached_value;
00637   }
00638   do {
00639     r = RAND_FACTOR*vmd_random()-1.f; 
00640     s = RAND_FACTOR*vmd_random()-1.f;
00641     w = r*r+s*s;
00642   } while (w >= 1.f);
00643   w = sqrtf(-2.f*logf(w)/w);
00644   cached_value = s * w;
00645   cache = true;
00646   return (r*w);
00647 }
00648 
00649 
00652 long vmd_get_total_physmem_mb(void) {
00653 #if defined(_MSC_VER)
00654   MEMORYSTATUS memstat;
00655   GlobalMemoryStatus(&memstat);
00656   if (memstat.dwLength != sizeof(memstat))
00657     return -1; /* memstat result is wrong size! */
00658   return memstat.dwTotalPhys/(1024 * 1024);
00659 #elif defined(__linux)
00660   FILE *fp;
00661   char meminfobuf[1024], *pos;
00662   size_t len;
00663 
00664   fp = fopen("/proc/meminfo", "r");
00665   if (fp != NULL) {
00666     len = fread(meminfobuf,1,1024, fp);
00667     meminfobuf[1023] = 0;
00668     fclose(fp);
00669     if (len > 0) {
00670       pos=strstr(meminfobuf,"MemTotal:");
00671       if (pos == NULL) 
00672         return -1;
00673       pos += 9; /* skip tag */;
00674       return strtol(pos, (char **)NULL, 10)/1024L;
00675     }
00676   } 
00677   return -1;
00678 #elif defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
00679   /* SysV Unix */
00680   long pgsz = sysconf(_SC_PAGESIZE);
00681   long physpgs = sysconf(_SC_PHYS_PAGES);
00682   return ((pgsz / 1024) * physpgs) / 1024;
00683 #elif defined(__APPLE__)
00684   /* MacOS X uses BSD sysctl */
00685   /* use hw.memsize, as it's a 64-bit value */
00686   int rc;
00687   uint64_t membytes;
00688   size_t len = sizeof(membytes);
00689   if (sysctlbyname("hw.memsize", &membytes, &len, NULL, 0)) 
00690     return -1;
00691   return (membytes / (1024*1024));
00692 #else
00693   return -1; /* unrecognized system, no method to get this info */
00694 #endif
00695 }
00696 
00697 
00698 
00701 long vmd_get_avail_physmem_mb(void) {
00702 #if defined(_MSC_VER)
00703   MEMORYSTATUS memstat;
00704   GlobalMemoryStatus(&memstat);
00705   if (memstat.dwLength != sizeof(memstat))
00706     return -1; /* memstat result is wrong size! */ 
00707   return memstat.dwAvailPhys / (1024 * 1024);
00708 #elif defined(__linux)
00709   FILE *fp;
00710   char meminfobuf[1024], *pos;
00711   size_t len;
00712   long val;
00713 
00714   fp = fopen("/proc/meminfo", "r");
00715   if (fp != NULL) {
00716     len = fread(meminfobuf,1,1024, fp);
00717     meminfobuf[1023] = 0;
00718     fclose(fp);
00719     if (len > 0) {
00720       val = 0L;
00721       pos=strstr(meminfobuf,"MemFree:");
00722       if (pos != NULL) {
00723         pos += 8; /* skip tag */;
00724         val += strtol(pos, (char **)NULL, 10);
00725       }
00726       pos=strstr(meminfobuf,"Buffers:");
00727       if (pos != NULL) {
00728         pos += 8; /* skip tag */;
00729         val += strtol(pos, (char **)NULL, 10);
00730       }
00731       pos=strstr(meminfobuf,"Cached:");
00732       if (pos != NULL) {
00733         pos += 8; /* skip tag */;
00734         val += strtol(pos, (char **)NULL, 10);
00735       }
00736       return val/1024L;
00737     } else {
00738       return -1;
00739     }
00740   } else {
00741     return -1;
00742   }
00743 #elif defined(_SC_PAGESIZE) && defined(_SC_AVPHYS_PAGES)
00744   /* SysV Unix */
00745   long pgsz = sysconf(_SC_PAGESIZE);
00746   long avphyspgs = sysconf(_SC_AVPHYS_PAGES);
00747   return ((pgsz / 1024) * avphyspgs) / 1024;
00748 #elif defined(__APPLE__)
00749 #if 0
00750   /* BSD sysctl */
00751   /* hw.usermem isn't really the amount of free memory, it's */
00752   /* really more a measure of the non-kernel memory          */
00753   int rc;
00754   int membytes;
00755   size_t len = sizeof(membytes);
00756   if (sysctlbyname("hw.usermem", &membytes, &len, NULL, 0)) 
00757     return -1;
00758   return (membytes / (1024*1024));
00759 #else
00760   return -1;
00761 #endif
00762 #else
00763   return -1; /* unrecognized system, no method to get this info */
00764 #endif
00765 }
00766 
00767 
00769 long vmd_get_avail_physmem_percent(void) {
00770   float total, avail;
00771   total = (float) vmd_get_total_physmem_mb();
00772   avail = (float) vmd_get_avail_physmem_mb();
00773   if (total >= 0.0 && avail >= 0.0)
00774     return (long) (avail / (total / 100.0));
00775 
00776   return -1; /* return an error */
00777 }
00778 
00779 

Generated on Sat Sep 6 01:27:14 2008 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002