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