annotate system/System.cpp @ 493:3931711b5671

* RDF importer: add model titles where possible * RDF transform factory: report whether something appears to be RDF or not (so we can avoid trying to load it as something else if the RDF query fails)
author Chris Cannam
date Tue, 25 Nov 2008 13:43:56 +0000
parents cff476cfce77
children ca208281238b
rev   line source
Chris@223 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@223 2
Chris@223 3 /*
Chris@223 4 Sonic Visualiser
Chris@223 5 An audio file viewer and annotation editor.
Chris@223 6 Centre for Digital Music, Queen Mary, University of London.
Chris@223 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@223 8
Chris@223 9 This program is free software; you can redistribute it and/or
Chris@223 10 modify it under the terms of the GNU General Public License as
Chris@223 11 published by the Free Software Foundation; either version 2 of the
Chris@223 12 License, or (at your option) any later version. See the file
Chris@223 13 COPYING included with this distribution for more information.
Chris@223 14 */
Chris@223 15
Chris@223 16 #include "System.h"
Chris@223 17
Chris@223 18 #include <QStringList>
Chris@223 19 #include <QString>
Chris@223 20
Chris@223 21 #include <stdint.h>
Chris@223 22
Chris@223 23 #ifndef _WIN32
Chris@223 24 #include <signal.h>
Chris@223 25 #include <sys/statvfs.h>
Chris@223 26 #endif
Chris@223 27
Chris@223 28 #ifdef __APPLE__
Chris@223 29 #include <sys/param.h>
Chris@223 30 #include <sys/sysctl.h>
Chris@223 31 #endif
Chris@223 32
Chris@405 33 #include <limits.h>
Chris@405 34 #include <cstdlib>
Chris@405 35
Chris@223 36 #include <iostream>
Chris@223 37
Chris@255 38 #ifdef __APPLE__
Chris@255 39 extern "C" {
Chris@255 40 void *
Chris@255 41 rpl_realloc (void *p, size_t n)
Chris@255 42 {
Chris@255 43 p = realloc(p, n);
Chris@255 44 if (p == 0 && n == 0)
Chris@255 45 {
Chris@255 46 p = malloc(0);
Chris@255 47 }
Chris@255 48 return p;
Chris@255 49 }
Chris@255 50 }
Chris@255 51 #endif
Chris@255 52
Chris@223 53 #ifdef _WIN32
Chris@223 54
Chris@223 55 extern "C" {
Chris@223 56
Chris@223 57 void usleep(unsigned long usec)
Chris@223 58 {
Chris@223 59 ::Sleep(usec / 1000);
Chris@223 60 }
Chris@223 61
Chris@223 62 void gettimeofday(struct timeval *tv, void *tz)
Chris@223 63 {
Chris@223 64 union {
Chris@223 65 long long ns100;
Chris@223 66 FILETIME ft;
Chris@223 67 } now;
Chris@223 68
Chris@223 69 ::GetSystemTimeAsFileTime(&now.ft);
Chris@223 70 tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL);
Chris@223 71 tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL);
Chris@223 72 }
Chris@223 73
Chris@223 74 }
Chris@223 75
Chris@223 76 #endif
Chris@223 77
Chris@223 78 ProcessStatus
Chris@223 79 GetProcessStatus(int pid)
Chris@223 80 {
Chris@223 81 #ifdef _WIN32
Chris@223 82 HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
Chris@223 83 if (!handle) {
Chris@223 84 return ProcessNotRunning;
Chris@223 85 } else {
Chris@223 86 CloseHandle(handle);
Chris@223 87 return ProcessRunning;
Chris@223 88 }
Chris@223 89 #else
Chris@223 90 if (kill(getpid(), 0) == 0) {
Chris@223 91 if (kill(pid, 0) == 0) {
Chris@223 92 return ProcessRunning;
Chris@223 93 } else {
Chris@223 94 return ProcessNotRunning;
Chris@223 95 }
Chris@223 96 } else {
Chris@223 97 return UnknownProcessStatus;
Chris@223 98 }
Chris@223 99 #endif
Chris@223 100 }
Chris@223 101
Chris@223 102 #ifdef _WIN32
Chris@223 103 /* MEMORYSTATUSEX is missing from older Windows headers, so define a
Chris@223 104 local replacement. This trick from MinGW source code. Ugh */
Chris@223 105 typedef struct
Chris@223 106 {
Chris@223 107 DWORD dwLength;
Chris@223 108 DWORD dwMemoryLoad;
Chris@223 109 DWORDLONG ullTotalPhys;
Chris@223 110 DWORDLONG ullAvailPhys;
Chris@223 111 DWORDLONG ullTotalPageFile;
Chris@223 112 DWORDLONG ullAvailPageFile;
Chris@223 113 DWORDLONG ullTotalVirtual;
Chris@223 114 DWORDLONG ullAvailVirtual;
Chris@223 115 DWORDLONG ullAvailExtendedVirtual;
Chris@223 116 } lMEMORYSTATUSEX;
Chris@223 117 typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*);
Chris@223 118 #endif
Chris@223 119
Chris@223 120 void
Chris@223 121 GetRealMemoryMBAvailable(int &available, int &total)
Chris@223 122 {
Chris@223 123 available = -1;
Chris@223 124 total = -1;
Chris@223 125
Chris@223 126 #ifdef _WIN32
Chris@223 127
Chris@223 128 static bool checked = false;
Chris@223 129 static bool exFound = false;
Chris@223 130 static PFN_MS_EX ex;
Chris@223 131
Chris@223 132 if (!checked) {
Chris@223 133
Chris@223 134 HMODULE h = GetModuleHandleA("kernel32.dll");
Chris@223 135
Chris@223 136 if (h) {
Chris@223 137 if ((ex = (PFN_MS_EX)GetProcAddress(h, "GlobalMemoryStatusEx"))) {
Chris@223 138 exFound = true;
Chris@223 139 }
Chris@223 140 }
Chris@223 141
Chris@223 142 checked = true;
Chris@223 143 }
Chris@223 144
Chris@223 145 DWORDLONG wavail = 0;
Chris@223 146 DWORDLONG wtotal = 0;
Chris@223 147
Chris@223 148 if (exFound) {
Chris@223 149
Chris@223 150 lMEMORYSTATUSEX lms;
Chris@223 151 lms.dwLength = sizeof(lms);
Chris@223 152 if (!ex(&lms)) {
Chris@223 153 std::cerr << "WARNING: GlobalMemoryStatusEx failed: error code "
Chris@223 154 << GetLastError() << std::endl;
Chris@223 155 return;
Chris@223 156 }
Chris@223 157 wavail = lms.ullAvailPhys;
Chris@223 158 wtotal = lms.ullTotalPhys;
Chris@223 159
Chris@223 160 } else {
Chris@223 161
Chris@223 162 /* Fall back to GlobalMemoryStatus which is always available.
Chris@223 163 but returns wrong results for physical memory > 4GB */
Chris@223 164
Chris@223 165 MEMORYSTATUS ms;
Chris@223 166 GlobalMemoryStatus(&ms);
Chris@223 167 wavail = ms.dwAvailPhys;
Chris@223 168 wtotal = ms.dwTotalPhys;
Chris@223 169 }
Chris@223 170
Chris@223 171 DWORDLONG size = wavail / 1048576;
Chris@223 172 if (size > INT_MAX) size = INT_MAX;
Chris@223 173 available = int(size);
Chris@223 174
Chris@223 175 size = wtotal / 1048576;
Chris@223 176 if (size > INT_MAX) size = INT_MAX;
Chris@223 177 total = int(size);
Chris@223 178
Chris@223 179 return;
Chris@223 180
Chris@223 181 #else
Chris@223 182 #ifdef __APPLE__
Chris@223 183
Chris@223 184 unsigned int val;
Chris@223 185 int mib[2];
Chris@223 186 size_t size_sys;
Chris@223 187
Chris@223 188 mib[0] = CTL_HW;
Chris@223 189
Chris@223 190 mib[1] = HW_PHYSMEM;
Chris@223 191 size_sys = sizeof(val);
Chris@223 192 sysctl(mib, 2, &val, &size_sys, NULL, 0);
Chris@223 193 if (val) total = val / 1048576;
Chris@223 194
Chris@223 195 mib[1] = HW_USERMEM;
Chris@223 196 size_sys = sizeof(val);
Chris@223 197 sysctl(mib, 2, &val, &size_sys, NULL, 0);
Chris@223 198 if (val) available = val / 1048576;
Chris@223 199
Chris@223 200 return;
Chris@223 201
Chris@223 202 #else
Chris@223 203
Chris@223 204 FILE *meminfo = fopen("/proc/meminfo", "r");
Chris@223 205 if (!meminfo) return;
Chris@223 206
Chris@223 207 char buf[256];
Chris@223 208 while (!feof(meminfo)) {
Chris@223 209 fgets(buf, 256, meminfo);
Chris@223 210 bool isMemFree = (strncmp(buf, "MemFree:", 8) == 0);
Chris@223 211 bool isMemTotal = (!isMemFree && (strncmp(buf, "MemTotal:", 9) == 0));
Chris@223 212 if (isMemFree || isMemTotal) {
Chris@223 213 QString line = QString(buf).trimmed();
Chris@223 214 QStringList elements = line.split(' ', QString::SkipEmptyParts);
Chris@223 215 QString unit = "kB";
Chris@223 216 if (elements.size() > 2) unit = elements[2];
Chris@223 217 int size = elements[1].toInt();
Chris@223 218 // std::cerr << "have size \"" << size << "\", unit \""
Chris@223 219 // << unit.toStdString() << "\"" << std::endl;
Chris@223 220 if (unit.toLower() == "gb") size = size * 1024;
Chris@223 221 else if (unit.toLower() == "mb") size = size;
Chris@223 222 else if (unit.toLower() == "kb") size = size / 1024;
Chris@223 223 else size = size / 1048576;
Chris@223 224
Chris@223 225 if (isMemFree) available = size;
Chris@223 226 else total = size;
Chris@223 227 }
Chris@223 228 if (available != -1 && total != -1) {
Chris@223 229 fclose(meminfo);
Chris@223 230 return;
Chris@223 231 }
Chris@223 232 }
Chris@223 233 fclose(meminfo);
Chris@223 234
Chris@223 235 return;
Chris@223 236
Chris@223 237 #endif
Chris@223 238 #endif
Chris@223 239 }
Chris@223 240
Chris@223 241 int
Chris@223 242 GetDiscSpaceMBAvailable(const char *path)
Chris@223 243 {
Chris@223 244 #ifdef _WIN32
Chris@223 245 ULARGE_INTEGER available, total, totalFree;
Chris@223 246 if (GetDiskFreeSpaceExA(path, &available, &total, &totalFree)) {
Chris@223 247 __int64 a = available.QuadPart;
Chris@223 248 a /= 1048576;
Chris@223 249 if (a > INT_MAX) a = INT_MAX;
Chris@223 250 return int(a);
Chris@223 251 } else {
Chris@223 252 std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code "
Chris@223 253 << GetLastError() << std::endl;
Chris@223 254 return -1;
Chris@223 255 }
Chris@223 256 #else
Chris@223 257 struct statvfs buf;
Chris@223 258 if (!statvfs(path, &buf)) {
Chris@223 259 // do the multiplies and divides in this order to reduce the
Chris@223 260 // likelihood of arithmetic overflow
Chris@436 261 // std::cerr << "statvfs(" << path << ") says available: " << buf.f_bavail << ", block size: " << buf.f_bsize << std::endl;
Chris@223 262 uint64_t available = ((buf.f_bavail / 1024) * buf.f_bsize) / 1024;
Chris@223 263 if (available > INT_MAX) available = INT_MAX;
Chris@223 264 return int(available);
Chris@223 265 } else {
Chris@223 266 perror("statvfs failed");
Chris@223 267 return -1;
Chris@223 268 }
Chris@223 269 #endif
Chris@223 270 }
Chris@303 271
Chris@303 272 static char *startupLocale = 0;
Chris@303 273
Chris@303 274 void
Chris@303 275 StoreStartupLocale()
Chris@303 276 {
Chris@303 277 char *loc = setlocale(LC_ALL, 0);
Chris@303 278 if (!loc) return;
Chris@303 279 if (startupLocale) free(startupLocale);
Chris@303 280 startupLocale = strdup(loc);
Chris@303 281 }
Chris@303 282
Chris@303 283 void
Chris@303 284 RestoreStartupLocale()
Chris@303 285 {
Chris@303 286 if (!startupLocale) {
Chris@303 287 setlocale(LC_ALL, "");
Chris@303 288 } else {
Chris@303 289 setlocale(LC_ALL, startupLocale);
Chris@303 290 }
Chris@303 291 }
Chris@223 292
Chris@223 293 double mod(double x, double y) { return x - (y * floor(x / y)); }
Chris@223 294 float modf(float x, float y) { return x - (y * floorf(x / y)); }
Chris@223 295
Chris@223 296 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; }
Chris@223 297 float princargf(float a) { return modf(a + M_PI, -2 * M_PI) + M_PI; }
Chris@223 298