00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00101
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
00160
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
00216
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
00257
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