System.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00002 
00003 /*
00004     Sonic Visualiser
00005     An audio file viewer and annotation editor.
00006     Centre for Digital Music, Queen Mary, University of London.
00007     This file copyright 2006 Chris Cannam and QMUL.
00008     
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of the
00012     License, or (at your option) any later version.  See the file
00013     COPYING included with this distribution for more information.
00014 */
00015 
00016 #include "System.h"
00017 
00018 #include <QStringList>
00019 #include <QString>
00020 
00021 #include <stdint.h>
00022 
00023 #ifndef _WIN32
00024 #include <signal.h>
00025 #include <sys/statvfs.h>
00026 #endif
00027 
00028 #ifdef __APPLE__
00029 #include <sys/param.h>
00030 #include <sys/sysctl.h>
00031 #endif
00032 
00033 #include <iostream>
00034 
00035 #ifdef __APPLE__
00036 extern "C" {
00037 void *
00038 rpl_realloc (void *p, size_t n)
00039 {
00040     p = realloc(p, n);
00041     if (p == 0 && n == 0)
00042     {
00043     p = malloc(0);
00044     }
00045     return p;
00046 }
00047 }
00048 #endif
00049 
00050 #ifdef _WIN32
00051 
00052 extern "C" {
00053 
00054 void usleep(unsigned long usec)
00055 {
00056     ::Sleep(usec / 1000);
00057 }
00058 
00059 void gettimeofday(struct timeval *tv, void *tz)
00060 {
00061     union { 
00062         long long ns100;  
00063         FILETIME ft; 
00064     } now; 
00065     
00066     ::GetSystemTimeAsFileTime(&now.ft); 
00067     tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); 
00068     tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); 
00069 }
00070 
00071 }
00072 
00073 #endif
00074 
00075 ProcessStatus
00076 GetProcessStatus(int pid)
00077 {
00078 #ifdef _WIN32
00079     HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
00080     if (!handle) {
00081         return ProcessNotRunning;
00082     } else {
00083         CloseHandle(handle);
00084         return ProcessRunning;
00085     }
00086 #else
00087     if (kill(getpid(), 0) == 0) {
00088         if (kill(pid, 0) == 0) {
00089             return ProcessRunning;
00090         } else {
00091             return ProcessNotRunning;
00092         }
00093     } else {
00094         return UnknownProcessStatus;
00095     }
00096 #endif
00097 }
00098 
00099 #ifdef _WIN32
00100 /*  MEMORYSTATUSEX is missing from older Windows headers, so define a
00101     local replacement.  This trick from MinGW source code.  Ugh */
00102 typedef struct
00103 {
00104     DWORD dwLength;
00105     DWORD dwMemoryLoad;
00106     DWORDLONG ullTotalPhys;
00107     DWORDLONG ullAvailPhys;
00108     DWORDLONG ullTotalPageFile;
00109     DWORDLONG ullAvailPageFile;
00110     DWORDLONG ullTotalVirtual;
00111     DWORDLONG ullAvailVirtual;
00112     DWORDLONG ullAvailExtendedVirtual;
00113 } lMEMORYSTATUSEX;
00114 typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
00115 #endif
00116 
00117 void
00118 GetRealMemoryMBAvailable(int &available, int &total)
00119 {
00120     available = -1;
00121     total = -1;
00122 
00123 #ifdef _WIN32
00124 
00125     static bool checked = false;
00126     static bool exFound = false;
00127     static PFN_MS_EX ex;
00128 
00129     if (!checked) {
00130 
00131         HMODULE h = GetModuleHandleA("kernel32.dll");
00132 
00133         if (h) {
00134             if ((ex = (PFN_MS_EX)GetProcAddress(h, "GlobalMemoryStatusEx"))) {
00135                 exFound = true;
00136             }
00137         }
00138         
00139         checked = true;
00140     }
00141 
00142     DWORDLONG wavail = 0;
00143     DWORDLONG wtotal = 0;
00144 
00145     if (exFound) {
00146 
00147         lMEMORYSTATUSEX lms;
00148         lms.dwLength = sizeof(lms);
00149         if (!ex(&lms)) {
00150             std::cerr << "WARNING: GlobalMemoryStatusEx failed: error code "
00151                       << GetLastError() << std::endl;
00152             return;
00153         }
00154         wavail = lms.ullAvailPhys;
00155         wtotal = lms.ullTotalPhys;
00156 
00157     } else {
00158 
00159         /* Fall back to GlobalMemoryStatus which is always available.
00160            but returns wrong results for physical memory > 4GB  */
00161 
00162         MEMORYSTATUS ms;
00163         GlobalMemoryStatus(&ms);
00164         wavail = ms.dwAvailPhys;
00165         wtotal = ms.dwTotalPhys;
00166     }
00167 
00168     DWORDLONG size = wavail / 1048576;
00169     if (size > INT_MAX) size = INT_MAX;
00170     available = int(size);
00171 
00172     size = wtotal / 1048576;
00173     if (size > INT_MAX) size = INT_MAX;
00174     total = int(size);
00175 
00176     return;
00177 
00178 #else
00179 #ifdef __APPLE__
00180 
00181     unsigned int val;
00182     int mib[2];
00183     size_t size_sys;
00184     
00185     mib[0] = CTL_HW;
00186 
00187     mib[1] = HW_PHYSMEM;
00188     size_sys = sizeof(val);
00189     sysctl(mib, 2, &val, &size_sys, NULL, 0);
00190     if (val) total = val / 1048576;
00191 
00192     mib[1] = HW_USERMEM;
00193     size_sys = sizeof(val);
00194     sysctl(mib, 2, &val, &size_sys, NULL, 0);
00195     if (val) available = val / 1048576;
00196 
00197     return;
00198 
00199 #else
00200 
00201     FILE *meminfo = fopen("/proc/meminfo", "r");
00202     if (!meminfo) return;
00203 
00204     char buf[256];
00205     while (!feof(meminfo)) {
00206         fgets(buf, 256, meminfo);
00207         bool isMemFree = (strncmp(buf, "MemFree:", 8) == 0);
00208         bool isMemTotal = (!isMemFree && (strncmp(buf, "MemTotal:", 9) == 0));
00209         if (isMemFree || isMemTotal) {
00210             QString line = QString(buf).trimmed();
00211             QStringList elements = line.split(' ', QString::SkipEmptyParts);
00212             QString unit = "kB";
00213             if (elements.size() > 2) unit = elements[2];
00214             int size = elements[1].toInt();
00215 //            std::cerr << "have size \"" << size << "\", unit \""
00216 //                      << unit.toStdString() << "\"" << std::endl;
00217             if (unit.toLower() == "gb") size = size * 1024;
00218             else if (unit.toLower() == "mb") size = size;
00219             else if (unit.toLower() == "kb") size = size / 1024;
00220             else size = size / 1048576;
00221 
00222             if (isMemFree) available = size;
00223             else total = size;
00224         }
00225         if (available != -1 && total != -1) {
00226             fclose(meminfo);
00227             return;
00228         }
00229     }
00230     fclose(meminfo);
00231 
00232     return;
00233 
00234 #endif
00235 #endif
00236 }
00237 
00238 int
00239 GetDiscSpaceMBAvailable(const char *path)
00240 {
00241 #ifdef _WIN32
00242     ULARGE_INTEGER available, total, totalFree;
00243     if (GetDiskFreeSpaceExA(path, &available, &total, &totalFree)) {
00244           __int64 a = available.QuadPart;
00245         a /= 1048576;
00246         if (a > INT_MAX) a = INT_MAX;
00247         return int(a);
00248     } else {
00249         std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code "
00250                   << GetLastError() << std::endl;
00251         return -1;
00252     }
00253 #else
00254     struct statvfs buf;
00255     if (!statvfs(path, &buf)) {
00256         // do the multiplies and divides in this order to reduce the
00257         // likelihood of arithmetic overflow
00258         std::cerr << "statvfs(" << path << ") says available: " << buf.f_bavail << ", block size: " << buf.f_bsize << std::endl;
00259         uint64_t available = ((buf.f_bavail / 1024) * buf.f_bsize) / 1024;
00260         if (available > INT_MAX) available = INT_MAX;
00261         return int(available);
00262     } else {
00263         perror("statvfs failed");
00264         return -1;
00265     }
00266 #endif
00267 }
00268 
00269 static char *startupLocale = 0;
00270 
00271 void
00272 StoreStartupLocale()
00273 {
00274     char *loc = setlocale(LC_ALL, 0);
00275     if (!loc) return;
00276     if (startupLocale) free(startupLocale);
00277     startupLocale = strdup(loc);
00278 }
00279 
00280 void
00281 RestoreStartupLocale()
00282 {
00283     if (!startupLocale) {
00284         setlocale(LC_ALL, "");
00285     } else {
00286         setlocale(LC_ALL, startupLocale);
00287     }
00288 }
00289 
00290 double mod(double x, double y) { return x - (y * floor(x / y)); }
00291 float modf(float x, float y) { return x - (y * floorf(x / y)); }
00292 
00293 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; }
00294 float princargf(float a) { return modf(a + M_PI, -2 * M_PI) + M_PI; }
00295 

Generated on Wed Feb 20 15:45:28 2008 for SonicVisualiser by  doxygen 1.5.1