Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/misc/darwin_memory_usage.c
4045 views
1
2
#if defined(__APPLE__)
3
4
#include <mach/host_info.h>
5
#include <mach/mach_host.h>
6
#include <mach/shared_region.h>
7
#include <mach/mach.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <sys/sysctl.h>
11
12
static inline cpu_type_t cpu_type() {
13
cpu_type_t cputype = 0;
14
15
int mib[CTL_MAXNAME];
16
size_t len = CTL_MAXNAME;
17
if (sysctlnametomib("sysctl.proc_cputype", mib, &len) != -1) {
18
mib[len] = getpid();
19
len++;
20
21
size_t cputypelen = sizeof(cputype);
22
if (sysctl(mib, len, &cputype, &cputypelen, 0, 0) == -1) {
23
cputype = 0;
24
}
25
}
26
27
return cputype;
28
}
29
30
static inline mach_vm_size_t shared_region_size(cpu_type_t cputype) {
31
switch(cputype) {
32
case CPU_TYPE_POWERPC:
33
return SHARED_REGION_SIZE_PPC;
34
case CPU_TYPE_POWERPC64:
35
return SHARED_REGION_SIZE_PPC64;
36
case CPU_TYPE_I386:
37
return SHARED_REGION_SIZE_I386;
38
case CPU_TYPE_X86_64:
39
return SHARED_REGION_SIZE_X86_64;
40
default: // unknown CPU type
41
return 0;
42
}
43
}
44
45
static inline int in_shared_region(cpu_type_t cputype, mach_vm_address_t address) {
46
if (cputype == CPU_TYPE_POWERPC &&
47
address >= SHARED_REGION_BASE_PPC &&
48
address <= (SHARED_REGION_BASE_PPC + SHARED_REGION_SIZE_PPC)) {
49
return 1;
50
}
51
52
if (cputype == CPU_TYPE_POWERPC64 &&
53
address >= SHARED_REGION_BASE_PPC64 &&
54
address <= (SHARED_REGION_BASE_PPC64 + SHARED_REGION_SIZE_PPC64)) {
55
return 1;
56
}
57
58
if (cputype == CPU_TYPE_I386 &&
59
address >= SHARED_REGION_BASE_I386 &&
60
address <= (SHARED_REGION_BASE_I386 + SHARED_REGION_SIZE_I386)) {
61
return 1;
62
}
63
64
if (cputype == CPU_TYPE_X86_64 &&
65
address >= SHARED_REGION_BASE_X86_64 &&
66
address <= (SHARED_REGION_BASE_X86_64 + SHARED_REGION_SIZE_X86_64)) {
67
return 1;
68
}
69
70
return 0;
71
}
72
73
unsigned long long darwin_virtual_size()
74
{
75
kern_return_t error;
76
task_t task;
77
struct task_basic_info_64 taskinfo;
78
cpu_type_t cputype;
79
mach_msg_type_number_t count;
80
mach_vm_size_t size;
81
mach_vm_address_t address;
82
mach_port_t object_name;
83
vm_region_top_info_data_t info;
84
mach_vm_size_t vsize;
85
mach_vm_size_t empty;
86
int has_shared_regions;
87
88
empty = 0;
89
90
count = TASK_BASIC_INFO_64_COUNT;
91
task = mach_task_self();
92
error = task_info(task, TASK_BASIC_INFO_64, (task_info_t)&taskinfo, &count);
93
94
if (error != KERN_SUCCESS) {
95
return 0;
96
}
97
98
vsize = taskinfo.virtual_size;
99
100
cputype = cpu_type();
101
102
// Go through all the vm regions and check to see if we should count them in the vsize or not
103
for (address = 0, has_shared_regions = 0; ; address += size) {
104
count = VM_REGION_TOP_INFO_COUNT;
105
if (mach_vm_region(task, &address, &size, VM_REGION_TOP_INFO, (vm_region_info_t)&info, &count, &object_name) != KERN_SUCCESS) {
106
// There are no more vm regions to look at.
107
break;
108
}
109
110
if (in_shared_region(cputype, address)) {
111
// Check if this process has the globally shared text and data regions mapped in.
112
// If so, set has_shared_regions to 1 and so we only check once.
113
if (has_shared_regions == 0 && info.share_mode == SM_EMPTY) {
114
vm_region_basic_info_data_64_t basic_info;
115
116
count = VM_REGION_BASIC_INFO_COUNT_64;
117
if (mach_vm_region(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&basic_info, &count, &object_name) != KERN_SUCCESS) {
118
break;
119
}
120
121
if (basic_info.reserved) {
122
has_shared_regions = 1;
123
}
124
}
125
126
// Skip the vm region if it is not a shared private region.
127
if (info.share_mode != SM_PRIVATE) {
128
continue;
129
}
130
}
131
132
if (info.share_mode == SM_EMPTY) {
133
empty += size;
134
}
135
}
136
137
// Subtract out the globally shared text and data region.
138
if (has_shared_regions == 1) {
139
vsize -= shared_region_size(cputype);
140
}
141
142
// Subtract out the empty pages (pagezero, stack guard, etc)
143
vsize -= empty;
144
145
return vsize;
146
}
147
148
#endif
149
150