File indexing completed on 2024-05-05 08:25:40
0001 // vim: set tabstop=4 shiftwidth=4 expandtab: 0002 /* 0003 Gwenview: an image viewer 0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org> 0005 Copyright (C) 2004-2005 by Enrico Ros <eros.kde@email.it> 0006 Copyright (C) 2004-2007 by Albert Astals Cid <aacid@kde.org> 0007 0008 This program is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU General Public License 0010 as published by the Free Software Foundation; either version 2 0011 of the License, or (at your option) any later version. 0012 0013 This program is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0016 GNU General Public License for more details. 0017 0018 You should have received a copy of the GNU General Public License 0019 along with this program; if not, write to the Free Software 0020 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA. 0021 0022 */ 0023 // Self 0024 #include "memoryutils.h" 0025 0026 // Qt 0027 #include <QFile> 0028 #include <QTextStream> 0029 #include <QTime> 0030 0031 // System 0032 #ifdef Q_OS_WIN 0033 #define _WIN32_WINNT 0x0500 0034 #include <windows.h> 0035 #elif defined(Q_OS_FREEBSD) 0036 #include <sys/types.h> 0037 0038 #include <sys/sysctl.h> // Must be included after sys/types.h 0039 #include <vm/vm_param.h> 0040 #endif 0041 0042 namespace Gwenview 0043 { 0044 namespace MemoryUtils 0045 { 0046 // This code has been copied from okular/core/document.cpp 0047 qulonglong getTotalMemory() 0048 { 0049 static qulonglong cachedValue = 0; 0050 if (cachedValue) 0051 return cachedValue; 0052 0053 #if defined(Q_OS_LINUX) 0054 // if /proc/meminfo doesn't exist, return 128MB 0055 QFile memFile(QStringLiteral("/proc/meminfo")); 0056 if (!memFile.open(QIODevice::ReadOnly)) 0057 return (cachedValue = 134217728); 0058 0059 QTextStream readStream(&memFile); 0060 while (true) { 0061 QString entry = readStream.readLine(); 0062 if (entry.isNull()) 0063 break; 0064 if (entry.startsWith(QLatin1String("MemTotal:"))) 0065 return (cachedValue = (Q_UINT64_C(1024) * entry.section(QLatin1Char(' '), -2, -2).toULongLong())); 0066 } 0067 #elif defined(Q_OS_FREEBSD) 0068 qulonglong physmem; 0069 int mib[] = {CTL_HW, HW_PHYSMEM}; 0070 size_t len = sizeof(physmem); 0071 if (sysctl(mib, 2, &physmem, &len, NULL, 0) == 0) 0072 return (cachedValue = physmem); 0073 #elif defined(Q_OS_WIN) 0074 MEMORYSTATUSEX stat; 0075 stat.dwLength = sizeof(stat); 0076 GlobalMemoryStatusEx(&stat); 0077 0078 return (cachedValue = stat.ullTotalPhys); 0079 #endif 0080 return (cachedValue = 134217728); 0081 } 0082 0083 qulonglong getFreeMemory() 0084 { 0085 static QTime lastUpdate = QTime::currentTime().addSecs(-3); 0086 static qulonglong cachedValue = 0; 0087 0088 if (qAbs(lastUpdate.secsTo(QTime::currentTime())) <= 2) 0089 return cachedValue; 0090 0091 #if defined(Q_OS_LINUX) 0092 // if /proc/meminfo doesn't exist, return MEMORY FULL 0093 QFile memFile(QStringLiteral("/proc/meminfo")); 0094 if (!memFile.open(QIODevice::ReadOnly)) 0095 return 0; 0096 0097 // read /proc/meminfo and sum up the contents of 'MemFree', 'Buffers' 0098 // and 'Cached' fields. consider swapped memory as used memory. 0099 qulonglong memoryFree = 0; 0100 QString entry; 0101 QTextStream readStream(&memFile); 0102 static const int nElems = 5; 0103 const QString names[nElems] = {QStringLiteral("MemFree:"), 0104 QStringLiteral("Buffers:"), 0105 QStringLiteral("Cached:"), 0106 QStringLiteral("SwapFree:"), 0107 QStringLiteral("SwapTotal:")}; 0108 qulonglong values[nElems] = {0, 0, 0, 0, 0}; 0109 bool foundValues[nElems] = {false, false, false, false, false}; 0110 while (true) { 0111 entry = readStream.readLine(); 0112 if (entry.isNull()) 0113 break; 0114 for (int i = 0; i < nElems; ++i) { 0115 if (entry.startsWith(names[i])) { 0116 values[i] = entry.section(QLatin1Char(' '), -2, -2).toULongLong(&foundValues[i]); 0117 } 0118 } 0119 } 0120 memFile.close(); 0121 bool found = true; 0122 for (int i = 0; found && i < nElems; ++i) 0123 found = found && foundValues[i]; 0124 if (found) { 0125 memoryFree = values[0] + values[1] + values[2] + values[3]; 0126 if (values[4] > memoryFree) 0127 memoryFree = 0; 0128 else 0129 memoryFree -= values[4]; 0130 } 0131 0132 lastUpdate = QTime::currentTime(); 0133 0134 return (cachedValue = (Q_UINT64_C(1024) * memoryFree)); 0135 #elif defined(Q_OS_FREEBSD) 0136 qulonglong cache, inact, free, psize; 0137 size_t cachelen, inactlen, freelen, psizelen; 0138 cachelen = sizeof(cache); 0139 inactlen = sizeof(inact); 0140 freelen = sizeof(free); 0141 psizelen = sizeof(psize); 0142 // sum up inactive, cached and free memory 0143 if (sysctlbyname("vm.stats.vm.v_cache_count", &cache, &cachelen, NULL, 0) == 0 0144 && sysctlbyname("vm.stats.vm.v_inactive_count", &inact, &inactlen, NULL, 0) == 0 0145 && sysctlbyname("vm.stats.vm.v_free_count", &free, &freelen, NULL, 0) == 0 0146 && sysctlbyname("vm.stats.vm.v_page_size", &psize, &psizelen, NULL, 0) == 0) { 0147 lastUpdate = QTime::currentTime(); 0148 return (cachedValue = (cache + inact + free) * psize); 0149 } else { 0150 return 0; 0151 } 0152 #elif defined(Q_OS_WIN) 0153 MEMORYSTATUSEX stat; 0154 stat.dwLength = sizeof(stat); 0155 GlobalMemoryStatusEx(&stat); 0156 0157 lastUpdate = QTime::currentTime(); 0158 0159 return (cachedValue = stat.ullAvailPhys); 0160 #else 0161 // tell the memory is full.. will act as in LOW profile 0162 return 0; 0163 #endif 0164 } 0165 0166 } // MemoryUtils namespace 0167 0168 } // Gwenview namespace