Developer Documentation
RAMInfo.cc
1 /*===========================================================================*\
2 * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40  \*===========================================================================*/
41 
42 #include "RAMInfo.hh"
43 
44 #include <QString>
45 #include <stdio.h>
46 
47 // Main Memory information
48 #ifdef WIN32
49 #include <Windows.h>
50 #elif defined ARCH_DARWIN
51 #include <mach/mach_host.h>
52 #include <mach/vm_statistics.h>
53 #include <sys/sysctl.h>
54 #include <sys/types.h>
55 #endif
56 // private struct to get ram information
57 namespace{
58 struct MemoryVacancy{
59  uint64_t totalRamMB;
60  uint64_t freeRamMB;
61  uint64_t bufferRamMB;
62 };
63 
64 void parseMeminfo(uint64_t& _total, uint64_t& _free, uint64_t& _buffer)
65 {
66  //use the specific type for scanf so we have at least 64 bit to read memory information
67  //this way we support memory information for max 9,223,372,036,854,775,807 byte of memory (that is 8 exa byte)
68  unsigned long long memcache, memfree, total, free, buffer;
69 
70  FILE* info = fopen("/proc/meminfo","r");
71  if(fscanf (info, "MemTotal: %19llu kB MemFree: %19llu kB Buffers: %19llu kB Cached: %19llu kB",&total, &memfree, &buffer, &memcache) < 4) //try to parse the old meminfo format
72  {
73  fclose(info);
74  info = fopen("/proc/meminfo","r");
75  //parsing the old format failed so we try to parse using the new format
76  if(fscanf(info, "MemTotal: %19llu kB MemFree: %19llu kB MemAvailable: %19llu kB Buffers: %19llu kB Cached: %19llu kB",&total, &memfree, &free, &buffer, &memcache) < 5)
77  {
78  //parsing failed overall so return 0 for all values
79  total = 0;
80  free = 0;
81  buffer = 0;
82  }
83  else
84  {
85  free = memfree + (buffer + memcache); //everything is fine
86  }
87 
88  }
89  else //compute available memory
90  {
91  free = memfree + (buffer + memcache);
92  }
93  fclose(info);
94  _total = total;
95  _free = free;
96  _buffer = buffer;
97 }
98 
99 }
100 namespace Utils
101 {
102  namespace Memory
103  {
104  void MemoryInfoUpdate(MemoryVacancy & _outMemoryVacancy) {
105 
106  //initialize to 0 just in case something fails or cant be read
107  _outMemoryVacancy.totalRamMB = 0;
108  _outMemoryVacancy.freeRamMB = 0;
109  _outMemoryVacancy.bufferRamMB = 0;
110 
111  // Main Memory information
112  #ifdef WIN32 //Windows
113  // Define memory structure
114  MEMORYSTATUSEX ms;
115  // Set the size ( required according to spec ... why???? )
116  ms.dwLength = sizeof(ms);
117  // Get the info
118  GlobalMemoryStatusEx(&ms);
119 
120  _outMemoryVacancy.totalRamMB = ms.ullTotalPhys / 1024 / 1024;
121  _outMemoryVacancy.freeRamMB = ms.ullAvailPhys / 1024 / 1024;
122 
123  #elif defined ARCH_DARWIN // Apple (sadly cant query free memory)
124  mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
125  vm_statistics_data_t vmstat;
126  if(KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count))
127  { // An error occurred
128  }
129  else
130  {
131  //retrieve real physical memory
132  int mib[2];
133  uint64_t physical_memory;
134  size_t length;
135  mib[0] = CTL_HW;
136  mib[1] = HW_MEMSIZE;
137  length = sizeof(uint64_t);
138  if( sysctl(mib, 2, &physical_memory, &length, NULL, 0) == -1 )
139  {
140  physical_memory = 0;
141  }
142  // retrieve free memory
143  _outMemoryVacancy.totalRamMB = physical_memory / 1024 / 1024;
144  unsigned long active = vmstat.active_count * PAGE_SIZE / 1024 / 1024;
145  _outMemoryVacancy.freeRamMB = _outMemoryVacancy.totalRamMB - active;
146  _outMemoryVacancy.bufferRamMB =0;
147  }
148 
149  #else // Linux
150 
151  uint64_t total, free, buffer;
152  parseMeminfo(total, free, buffer);
153 
154  // Unit in kbytes ; /1024 -> MB
155  _outMemoryVacancy.totalRamMB = total / 1024;
156  _outMemoryVacancy.freeRamMB = free / 1024;
157  _outMemoryVacancy.bufferRamMB = buffer / 1024; // Buffers get freed, if we don't have enough free ram
158  #endif
159  }
160 
161  uint64_t queryFreeRAM()
162  {
163  MemoryVacancy vac;
164  MemoryInfoUpdate(vac);
165  return vac.freeRamMB;
166  }
167 
168  uint64_t queryTotalRAM()
169  {
170  MemoryVacancy vac;
171  MemoryInfoUpdate(vac);
172  return vac.totalRamMB;
173  }
174 
175  uint64_t queryBufferedRAM()
176  {
177  MemoryVacancy vac;
178  MemoryInfoUpdate(vac);
179  return vac.bufferRamMB;
180  }
181  }
182 }
unsigned long long uint64_t
Definition: SR_types.hh:89