Chris@150: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@150: Chris@150: /* Chris@150: Sonic Visualiser Chris@150: An audio file viewer and annotation editor. Chris@150: Centre for Digital Music, Queen Mary, University of London. Chris@202: This file copyright 2006 Chris Cannam and QMUL. Chris@150: Chris@150: This program is free software; you can redistribute it and/or Chris@150: modify it under the terms of the GNU General Public License as Chris@150: published by the Free Software Foundation; either version 2 of the Chris@150: License, or (at your option) any later version. See the file Chris@150: COPYING included with this distribution for more information. Chris@150: */ Chris@150: Chris@150: #include "System.h" Chris@150: Chris@168: #include Chris@168: #include Chris@168: Chris@170: #include Chris@170: Chris@150: #ifndef _WIN32 Chris@150: #include Chris@168: #include Chris@150: #endif Chris@150: Martin@196: #ifdef __APPLE__ Martin@196: #include Martin@196: #include Martin@196: #endif Martin@196: Chris@150: #include Chris@150: Chris@150: #ifdef _WIN32 Chris@150: Chris@150: extern "C" { Chris@150: Chris@150: void usleep(unsigned long usec) Chris@150: { Chris@150: ::Sleep(usec / 1000); Chris@150: } Chris@150: Chris@150: void gettimeofday(struct timeval *tv, void *tz) Chris@150: { Chris@150: union { Chris@150: long long ns100; Chris@150: FILETIME ft; Chris@150: } now; Chris@150: Chris@150: ::GetSystemTimeAsFileTime(&now.ft); Chris@150: tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); Chris@150: tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); Chris@150: } Chris@150: Chris@150: } Chris@150: Chris@150: #endif Chris@150: Chris@150: ProcessStatus Chris@150: GetProcessStatus(int pid) Chris@150: { Chris@150: #ifdef _WIN32 Chris@150: HANDLE handle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); Chris@150: if (!handle) { Chris@150: return ProcessNotRunning; Chris@150: } else { Chris@150: CloseHandle(handle); Chris@150: return ProcessRunning; Chris@150: } Chris@150: #else Chris@150: if (kill(getpid(), 0) == 0) { Chris@150: if (kill(pid, 0) == 0) { Chris@150: return ProcessRunning; Chris@150: } else { Chris@150: return ProcessNotRunning; Chris@150: } Chris@150: } else { Chris@150: return UnknownProcessStatus; Chris@150: } Chris@150: #endif Chris@150: } Chris@150: Chris@170: void Chris@170: GetRealMemoryMBAvailable(int &available, int &total) Chris@168: { Chris@170: available = -1; Chris@170: total = -1; Chris@170: Chris@171: #ifdef _WIN32 Chris@171: Chris@171: MEMORYSTATUSEX status; Chris@171: status.dwLength = sizeof(status); Chris@171: if (!GlobalMemoryStatusEx(&status)) { Chris@171: std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code " Chris@171: << GetLastError() << std::endl; Chris@171: return; Chris@171: } Chris@171: DWORDLONG size = status.ullAvailPhys / 1048576; Chris@171: if (size > INT_MAX) size = INT_MAX; Chris@171: available = int(size); Chris@171: Chris@171: size = status.ullTotalPhys / 1048576; Chris@171: if (size > INT_MAX) size = INT_MAX; Chris@171: total = int(size); Chris@171: Chris@171: return; Chris@171: Chris@171: #else Chris@171: #ifdef __APPLE__ Chris@171: Chris@171: unsigned int val; Chris@171: int mib[2]; Chris@171: size_t size_sys; Chris@171: Chris@171: mib[0] = CTL_HW; Chris@171: Chris@171: mib[1] = HW_PHYSMEM; Chris@171: size_sys = sizeof(val); Chris@171: sysctl(mib, 2, &val, &size_sys, NULL, 0); Chris@171: if (val) total = val / 1048576; Chris@171: Chris@171: mib[1] = HW_USERMEM; Chris@171: size_sys = sizeof(val); Chris@171: sysctl(mib, 2, &val, &size_sys, NULL, 0); Chris@171: if (val) available = val / 1048576; Chris@171: Chris@171: return; Chris@171: Chris@171: #else Chris@171: Chris@169: FILE *meminfo = fopen("/proc/meminfo", "r"); Chris@170: if (!meminfo) return; Chris@169: Chris@169: char buf[256]; Chris@169: while (!feof(meminfo)) { Chris@169: fgets(buf, 256, meminfo); Chris@170: bool isMemFree = (strncmp(buf, "MemFree:", 8) == 0); Chris@170: bool isMemTotal = (!isMemFree && (strncmp(buf, "MemTotal:", 9) == 0)); Chris@170: if (isMemFree || isMemTotal) { Chris@169: QString line = QString(buf).trimmed(); Chris@169: QStringList elements = line.split(' ', QString::SkipEmptyParts); Chris@169: QString unit = "kB"; Chris@169: if (elements.size() > 2) unit = elements[2]; Chris@169: int size = elements[1].toInt(); Chris@169: // std::cerr << "have size \"" << size << "\", unit \"" Chris@169: // << unit.toStdString() << "\"" << std::endl; Chris@170: if (unit.toLower() == "gb") size = size * 1024; Chris@170: else if (unit.toLower() == "mb") size = size; Chris@170: else if (unit.toLower() == "kb") size = size / 1024; Chris@170: else size = size / 1048576; Chris@170: Chris@170: if (isMemFree) available = size; Chris@170: else total = size; Chris@170: } Chris@170: if (available != -1 && total != -1) { Chris@170: fclose(meminfo); Chris@170: return; Chris@168: } Chris@168: } Chris@169: fclose(meminfo); Chris@171: Chris@171: return; Chris@171: Chris@171: #endif Chris@171: #endif Chris@168: } Chris@168: Chris@168: int Chris@168: GetDiscSpaceMBAvailable(const char *path) Chris@168: { Chris@168: #ifdef _WIN32 Chris@168: __int64 available, total, totalFree; Chris@168: if (GetDiskFreeSpaceEx(path, &available, &total, &totalFree)) { Chris@168: available /= 1048576; Chris@170: if (available > INT_MAX) available = INT_MAX; Chris@168: return int(available); Chris@168: } else { Chris@168: std::cerr << "WARNING: GetDiskFreeSpaceEx failed: error code " Chris@168: << GetLastError() << std::endl; Chris@168: return -1; Chris@168: } Chris@168: #else Chris@168: struct statvfs buf; Chris@168: if (!statvfs(path, &buf)) { Chris@168: // do the multiplies and divides in this order to reduce the Chris@168: // likelihood of arithmetic overflow Chris@168: std::cerr << "statvfs(" << path << ") says available: " << buf.f_bavail << ", block size: " << buf.f_bsize << std::endl; Chris@170: uint64_t available = ((buf.f_bavail / 1024) * buf.f_bsize) / 1024; Chris@170: if (available > INT_MAX) available = INT_MAX; Chris@170: return int(available); Chris@168: } else { Chris@168: perror("statvfs failed"); Chris@168: return -1; Chris@168: } Chris@168: #endif Chris@168: } Chris@168: Chris@168: Chris@150: double mod(double x, double y) { return x - (y * floor(x / y)); } Chris@150: float modf(float x, float y) { return x - (y * floorf(x / y)); } Chris@150: Chris@150: double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } Chris@150: float princargf(float a) { return modf(a + M_PI, -2 * M_PI) + M_PI; } Chris@150: