Mercurial > hg > svcore
comparison system/System.cpp @ 1365:3382d914e110
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:44 +0000 |
parents | 39271c98cbdd |
children | cc62d7862203 |
comparison
equal
deleted
inserted
replaced
1272:6a7ea3bd0e10 | 1365:3382d914e110 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ |
2 | 2 |
3 /* | 3 /* |
4 Sonic Visualiser | 4 Sonic Visualiser |
5 An audio file viewer and annotation editor. | 5 An audio file viewer and annotation editor. |
6 Centre for Digital Music, Queen Mary, University of London. | 6 Centre for Digital Music, Queen Mary, University of London. |
7 This file copyright 2006 Chris Cannam and QMUL. | 7 This file copyright 2006 Chris Cannam and QMUL. |
8 | 8 |
9 This program is free software; you can redistribute it and/or | 9 This program is free software; you can redistribute it and/or |
10 modify it under the terms of the GNU General Public License as | 10 modify it under the terms of the GNU General Public License as |
11 published by the Free Software Foundation; either version 2 of the | 11 published by the Free Software Foundation; either version 2 of the |
12 License, or (at your option) any later version. See the file | 12 License, or (at your option) any later version. See the file |
13 COPYING included with this distribution for more information. | 13 COPYING included with this distribution for more information. |
14 */ | 14 */ |
15 | 15 |
16 #include "System.h" | 16 #include "System.h" |
17 | 17 |
18 #include <QStringList> | 18 #include <QStringList> |
37 | 37 |
38 #include <iostream> | 38 #include <iostream> |
39 | 39 |
40 #ifdef __APPLE__ | 40 #ifdef __APPLE__ |
41 extern "C" { | 41 extern "C" { |
42 void * | 42 void * |
43 rpl_realloc (void *p, size_t n) | 43 rpl_realloc (void *p, size_t n) |
44 { | |
45 p = realloc(p, n); | |
46 if (p == 0 && n == 0) | |
47 { | 44 { |
48 p = malloc(0); | 45 p = realloc(p, n); |
49 } | 46 if (p == 0 && n == 0) |
50 return p; | 47 { |
51 } | 48 p = malloc(0); |
49 } | |
50 return p; | |
51 } | |
52 } | 52 } |
53 #endif | 53 #endif |
54 | 54 |
55 #ifdef _WIN32 | 55 #ifdef _WIN32 |
56 | 56 |
57 extern "C" { | 57 extern "C" { |
58 | 58 |
59 /* usleep is now in mingw | 59 #ifdef _MSC_VER |
60 void usleep(unsigned long usec) | 60 void usleep(unsigned long usec) |
61 { | 61 { |
62 ::Sleep(usec / 1000); | 62 ::Sleep(usec / 1000); |
63 } | 63 } |
64 */ | 64 #endif |
65 | 65 |
66 int gettimeofday(struct timeval *tv, void *tz) | 66 int gettimeofday(struct timeval *tv, void *tz) |
67 { | 67 { |
68 union { | 68 union { |
69 long long ns100; | 69 long long ns100; |
70 FILETIME ft; | 70 FILETIME ft; |
71 } now; | 71 } now; |
72 | 72 |
73 ::GetSystemTimeAsFileTime(&now.ft); | 73 ::GetSystemTimeAsFileTime(&now.ft); |
74 tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); | 74 tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); |
75 tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); | 75 tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); |
76 return 0; | 76 return 0; |
77 } | 77 } |
78 | 78 |
79 } | 79 } |
80 | 80 |
81 #endif | 81 #endif |
82 | 82 |
117 DWORDLONG ullAvailPageFile; | 117 DWORDLONG ullAvailPageFile; |
118 DWORDLONG ullTotalVirtual; | 118 DWORDLONG ullTotalVirtual; |
119 DWORDLONG ullAvailVirtual; | 119 DWORDLONG ullAvailVirtual; |
120 DWORDLONG ullAvailExtendedVirtual; | 120 DWORDLONG ullAvailExtendedVirtual; |
121 } lMEMORYSTATUSEX; | 121 } lMEMORYSTATUSEX; |
122 typedef WINBOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*); | 122 typedef BOOL (WINAPI *PFN_MS_EX) (lMEMORYSTATUSEX*); |
123 #endif | 123 #endif |
124 | 124 |
125 void | 125 void |
126 GetRealMemoryMBAvailable(ssize_t &available, ssize_t &total) | 126 GetRealMemoryMBAvailable(ssize_t &available, ssize_t &total) |
127 { | 127 { |
151 DWORDLONG wtotal = 0; | 151 DWORDLONG wtotal = 0; |
152 | 152 |
153 if (exFound) { | 153 if (exFound) { |
154 | 154 |
155 lMEMORYSTATUSEX lms; | 155 lMEMORYSTATUSEX lms; |
156 lms.dwLength = sizeof(lms); | 156 lms.dwLength = sizeof(lms); |
157 if (!ex(&lms)) { | 157 if (!ex(&lms)) { |
158 cerr << "WARNING: GlobalMemoryStatusEx failed: error code " | 158 cerr << "WARNING: GlobalMemoryStatusEx failed: error code " |
159 << GetLastError() << endl; | 159 << GetLastError() << endl; |
160 return; | 160 return; |
161 } | 161 } |
162 wavail = lms.ullAvailPhys; | 162 wavail = lms.ullAvailPhys; |
163 wtotal = lms.ullTotalPhys; | 163 wtotal = lms.ullTotalPhys; |
164 | 164 |
165 } else { | 165 } else { |
166 | 166 |
167 /* Fall back to GlobalMemoryStatus which is always available. | 167 /* Fall back to GlobalMemoryStatus which is always available. |
168 but returns wrong results for physical memory > 4GB */ | 168 but returns wrong results for physical memory > 4GB */ |
169 | 169 |
170 MEMORYSTATUS ms; | 170 MEMORYSTATUS ms; |
171 GlobalMemoryStatus(&ms); | 171 GlobalMemoryStatus(&ms); |
172 wavail = ms.dwAvailPhys; | 172 wavail = ms.dwAvailPhys; |
173 wtotal = ms.dwTotalPhys; | 173 wtotal = ms.dwTotalPhys; |
174 } | 174 } |
175 | 175 |
176 DWORDLONG size = wavail / 1048576; | 176 DWORDLONG size = wavail / 1048576; |
177 if (size > INT_MAX) size = INT_MAX; | 177 if (size > INT_MAX) size = INT_MAX; |
209 FILE *meminfo = fopen("/proc/meminfo", "r"); | 209 FILE *meminfo = fopen("/proc/meminfo", "r"); |
210 if (!meminfo) return; | 210 if (!meminfo) return; |
211 | 211 |
212 char buf[256]; | 212 char buf[256]; |
213 while (!feof(meminfo)) { | 213 while (!feof(meminfo)) { |
214 fgets(buf, 256, meminfo); | 214 if (!fgets(buf, 256, meminfo)) { |
215 return; | |
216 } | |
215 bool isMemFree = (strncmp(buf, "MemFree:", 8) == 0); | 217 bool isMemFree = (strncmp(buf, "MemFree:", 8) == 0); |
216 bool isMemTotal = (!isMemFree && (strncmp(buf, "MemTotal:", 9) == 0)); | 218 bool isMemTotal = (!isMemFree && (strncmp(buf, "MemTotal:", 9) == 0)); |
217 if (isMemFree || isMemTotal) { | 219 if (isMemFree || isMemTotal) { |
218 QString line = QString(buf).trimmed(); | 220 QString line = QString(buf).trimmed(); |
219 QStringList elements = line.split(' ', QString::SkipEmptyParts); | 221 QStringList elements = line.split(' ', QString::SkipEmptyParts); |
247 GetDiscSpaceMBAvailable(const char *path) | 249 GetDiscSpaceMBAvailable(const char *path) |
248 { | 250 { |
249 #ifdef _WIN32 | 251 #ifdef _WIN32 |
250 ULARGE_INTEGER available, total, totalFree; | 252 ULARGE_INTEGER available, total, totalFree; |
251 if (GetDiskFreeSpaceExA(path, &available, &total, &totalFree)) { | 253 if (GetDiskFreeSpaceExA(path, &available, &total, &totalFree)) { |
252 __int64 a = available.QuadPart; | 254 __int64 a = available.QuadPart; |
253 a /= 1048576; | 255 a /= 1048576; |
254 if (a > INT_MAX) a = INT_MAX; | 256 if (a > INT_MAX) a = INT_MAX; |
255 return ssize_t(a); | 257 return ssize_t(a); |
256 } else { | 258 } else { |
257 cerr << "WARNING: GetDiskFreeSpaceEx failed: error code " | 259 cerr << "WARNING: GetDiskFreeSpaceEx failed: error code " |
258 << GetLastError() << endl; | 260 << GetLastError() << endl; |
259 return -1; | 261 return -1; |
260 } | 262 } |
261 #else | 263 #else |
262 struct statvfs buf; | 264 struct statvfs buf; |
263 if (!statvfs(path, &buf)) { | 265 if (!statvfs(path, &buf)) { |
275 } | 277 } |
276 | 278 |
277 #ifdef _WIN32 | 279 #ifdef _WIN32 |
278 extern void SystemMemoryBarrier() | 280 extern void SystemMemoryBarrier() |
279 { | 281 { |
280 #ifdef __MSVC__ | 282 #ifdef _MSC_VER |
281 MemoryBarrier(); | 283 MemoryBarrier(); |
282 #else /* mingw */ | 284 #else /* mingw */ |
283 LONG Barrier = 0; | 285 LONG Barrier = 0; |
284 __asm__ __volatile__("xchgl %%eax,%0 " | 286 __asm__ __volatile__("xchgl %%eax,%0 " |
285 : "=r" (Barrier)); | 287 : "=r" (Barrier)); |
286 #endif | 288 #endif |
287 } | 289 } |
288 #else /* !_WIN32 */ | 290 #else /* !_WIN32 */ |
289 #if !defined(__APPLE__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)) | 291 #if !defined(__APPLE__) && defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)) |
290 void | 292 void |
291 SystemMemoryBarrier() | 293 SystemMemoryBarrier() |
292 { | 294 { |
293 pthread_mutex_t dummy = PTHREAD_MUTEX_INITIALIZER; | 295 pthread_mutex_t dummy = PTHREAD_MUTEX_INITIALIZER; |
294 pthread_mutex_lock(&dummy); | 296 pthread_mutex_lock(&dummy); |
323 float modf(float x, float y) { return x - (y * floorf(x / y)); } | 325 float modf(float x, float y) { return x - (y * floorf(x / y)); } |
324 | 326 |
325 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } | 327 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } |
326 float princargf(float a) { return float(princarg(a)); } | 328 float princargf(float a) { return float(princarg(a)); } |
327 | 329 |
328 #ifdef _WIN32 | 330 |
329 | |
330 PluginLoadStatus | |
331 TestPluginLoadability(QString soname, QString descriptorFn) | |
332 { | |
333 //!!! Can't do the POSIX logic below, but we have no good | |
334 // alternative here yet | |
335 return PluginLoadOK; | |
336 } | |
337 | |
338 #else | |
339 | |
340 #include <unistd.h> | |
341 #include <sys/wait.h> | |
342 | |
343 PluginLoadStatus | |
344 TestPluginLoadability(QString soname, QString descriptorFn) | |
345 { | |
346 //!!! This is POSIX only, no equivalent on Windows, where we'll | |
347 //!!! have to do something completely different | |
348 | |
349 pid_t pid = fork(); | |
350 | |
351 if (pid < 0) { | |
352 return UnknownPluginLoadStatus; // fork failed | |
353 } | |
354 | |
355 if (pid == 0) { // the child process | |
356 | |
357 void *handle = DLOPEN(soname, RTLD_NOW | RTLD_LOCAL); | |
358 if (!handle) { | |
359 cerr << "isPluginLibraryLoadable: Failed to open plugin library \"" | |
360 << soname << "\": " << dlerror() << "\n"; | |
361 cerr << "exiting with status 1" << endl; | |
362 exit(1); | |
363 } | |
364 | |
365 void *fn = DLSYM(handle, descriptorFn.toLocal8Bit().data()); | |
366 if (!fn) { | |
367 cerr << "isPluginLibraryLoadable: Failed to find plugin descriptor function \"" << descriptorFn << "\" in library \"" << soname << "\": " << dlerror() << "\n"; | |
368 exit(2); | |
369 } | |
370 | |
371 // cerr << "isPluginLibraryLoadable: Successfully loaded library \"" << soname << "\" and retrieved descriptor function" << endl; | |
372 | |
373 exit(0); | |
374 | |
375 } else { // the parent process | |
376 | |
377 int status = 0; | |
378 | |
379 do { | |
380 waitpid(pid, &status, 0); | |
381 } while (WIFSTOPPED(status)); | |
382 | |
383 if (WIFEXITED(status)) { | |
384 switch (WEXITSTATUS(status)) { | |
385 case 0: return PluginLoadOK; // success | |
386 case 1: return PluginLoadFailedToLoadLibrary; | |
387 case 2: return PluginLoadFailedToFindDescriptor; | |
388 default: return PluginLoadFailedElsewhere; | |
389 } | |
390 } | |
391 | |
392 if (WIFSIGNALED(status)) { | |
393 return PluginLoadFailedElsewhere; | |
394 } | |
395 | |
396 return UnknownPluginLoadStatus; | |
397 } | |
398 } | |
399 | |
400 #endif |