fw4spl
DarwinMemoryMonitorTools.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2017.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #ifdef __MACOSX__
8 
9 #include "fwMemory/tools/DarwinMemoryMonitorTools.hpp"
10 
11 #include <fwCore/base.hpp>
12 
13 #include <mach/mach.h>
14 #include <mach/mach_host.h>
15 #include <mach/mach_init.h>
16 #include <mach/mach_types.h>
17 #include <mach/vm_statistics.h>
18 
19 #include <sys/sysctl.h>
20 #include <sys/types.h>
21 
22 #include <iomanip>
23 #include <iostream>
24 
25 namespace fwMemory
26 {
27 namespace tools
28 {
29 
30 //-----------------------------------------------------------------------------
31 
32 DarwinMemoryMonitorTools::DarwinMemoryMonitorTools()
33 {
34 }
35 
36 //-----------------------------------------------------------------------------
37 
38 DarwinMemoryMonitorTools::~DarwinMemoryMonitorTools()
39 {
40 }
41 
42 //-----------------------------------------------------------------------------
43 
44 std::uint64_t DarwinMemoryMonitorTools::estimateFreeMem()
45 {
46  std::uint64_t freeMemory = 0;
47 
48  freeMemory = getFreeSystemMemory();
49 
50 #ifndef __LP64__
51  struct task_basic_info t_info;
52  mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
53 
54  if (KERN_SUCCESS != task_info(mach_task_self(),
55  TASK_BASIC_INFO, (task_info_t)&t_info,
56  &t_info_count))
57  {
58  SLM_ASSERT("Failed to retrieve used process memory information", 0);
59  return 0;
60  }
61 
62  // Hard coded 3Gb limit for 32bit process
63  const std::uint64_t maxMemory = 3221225472LL; // 3 Go
64  const std::uint64_t usedProcessMemory = getUsedProcessMemory();
65  freeMemory = std::min( maxMemory - usedProcessMemory, freeMemory);
66  const std::uint64_t maxVMemory = 4294967296LL; // 4 Go
67  freeMemory = std::min( maxVMemory - t_info.virtual_size, freeMemory);
68 #endif
69 
70  return freeMemory;
71 }
72 
73 //-----------------------------------------------------------------------------
74 
75 void DarwinMemoryMonitorTools::printProcessMemoryInformation()
76 {
77 }
78 
79 //-----------------------------------------------------------------------------
80 
81 void DarwinMemoryMonitorTools::printSystemMemoryInformation()
82 {
83 }
84 
85 //-----------------------------------------------------------------------------
86 
87 void DarwinMemoryMonitorTools::printMemoryInformation()
88 {
89  printSystemMemoryInformation();
90  printProcessMemoryInformation();
91 }
92 
93 //-----------------------------------------------------------------------------
94 
95 std::uint64_t DarwinMemoryMonitorTools::getTotalSystemMemory()
96 {
97  static int64_t physical_memory = 0;
98 
99  if (physical_memory == 0)
100  {
101  int mib[2];
102  mib[0] = CTL_HW;
103  mib[1] = HW_MEMSIZE;
104  size_t length = sizeof(int64_t);
105  sysctl(mib, 2, &physical_memory, &length, NULL, 0);
106  }
107 
108  return physical_memory;
109 }
110 
111 //-----------------------------------------------------------------------------
112 
113 std::uint64_t DarwinMemoryMonitorTools::getUsedSystemMemory()
114 {
115  vm_size_t page_size;
116  mach_port_t mach_port;
117  mach_msg_type_number_t count;
118  vm_statistics_data_t vm_stats;
119 
120  mach_port = mach_host_self();
121  count = sizeof(vm_stats) / sizeof(natural_t);
122  if (KERN_SUCCESS == host_page_size(mach_port, &page_size) &&
123  KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO,
124  (host_info_t)&vm_stats, &count))
125  {
126  uint64_t used_memory = (
127  (int64_t)vm_stats.active_count +
128  (int64_t)vm_stats.wire_count
129  ) * (int64_t)page_size;
130 
131  return used_memory;
132  }
133  SLM_ASSERT("Failed to retrieve used system memory information", 0);
134  return 0;
135 }
136 
137 //-----------------------------------------------------------------------------
138 
139 std::uint64_t DarwinMemoryMonitorTools::getFreeSystemMemory()
140 {
141  vm_size_t page_size;
142  mach_port_t mach_port;
143  mach_msg_type_number_t count;
144  vm_statistics_data_t vm_stats;
145 
146  mach_port = mach_host_self();
147  count = sizeof(vm_stats) / sizeof(natural_t);
148  if (KERN_SUCCESS == host_page_size(mach_port, &page_size) &&
149  KERN_SUCCESS == host_statistics(mach_port, HOST_VM_INFO,
150  (host_info_t)&vm_stats, &count))
151  {
152  uint64_t freeMemory = (
153  (int64_t)vm_stats.free_count +
154  (int64_t)vm_stats.inactive_count
155  ) * (int64_t)page_size;
156  return freeMemory;
157  }
158  SLM_ASSERT("Failed to retrieve free system memory information", 0);
159  return 0;
160 }
161 
162 //-----------------------------------------------------------------------------
163 
164 std::uint64_t DarwinMemoryMonitorTools::getUsedProcessMemory()
165 {
166  struct task_basic_info t_info;
167  mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
168 
169  if (KERN_SUCCESS != task_info(mach_task_self(),
170  TASK_BASIC_INFO, (task_info_t)&t_info,
171  &t_info_count))
172  {
173  SLM_ASSERT("Failed to retrieve used process memory information", 0);
174  return 0;
175  }
176 
177  return t_info.resident_size;
178 }
179 
180 //-----------------------------------------------------------------------------
181 
182 } // namespace tools
183 } // namespace fwMemory
184 
185 #endif
The namespace fwMemory contains tools to manage memory. Use for dump.
Definition: SReader.hpp:20
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308