Skip to content

Commit 1387852

Browse files
committed
sysmon: Mac RAM check
1 parent a7d806c commit 1387852

File tree

1 file changed

+53
-6
lines changed

1 file changed

+53
-6
lines changed

sysmon.c

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include <sys/sysinfo.h>
1313
#include <sys/resource.h>
1414
#endif
15+
#ifdef __APPLE__
16+
#include <sys/sysctl.h>
17+
#include <sys/resource.h>
18+
#include <mach/mach.h>
19+
#endif
1520

1621
#include "common.h"
1722
#include "epoch.h"
@@ -59,14 +64,12 @@ void sysmon() {
5964
int64_t currentMs = currentTick * SYSMON_TICK_MS;
6065

6166
// First: check that we have a reasonable amount of free RAM.
62-
#ifdef __linux__
6367
// TODO: move this check to userspace.
6468
if (currentTick % 1000 == 0) {
6569
// assuming that ticks happen every 2ms, this should happen
6670
// every 2s.
6771
checkRam();
6872
}
69-
#endif
7073

7174
// Second: deal with any remove-later statements that we should
7275
// remove.
@@ -221,10 +224,10 @@ static void checkRam() {
221224
// detect leaks (I think system RAM is good for killing but
222225
// process RAM use is better for leak diagnosis).
223226
struct rusage ru; getrusage(RUSAGE_SELF, &ru);
224-
/* fprintf(stderr, "Check avail system RAM: %d MB / %d MB\n" */
225-
/* "Check self RAM usage: %ld MB\n", */
226-
/* freeRamMb, totalRamMb, */
227-
/* ru.ru_maxrss / 1024); */
227+
fprintf(stderr, "Check avail system RAM: %d MB / %d MB\n"
228+
"Check self RAM usage: %ld MB\n",
229+
freeRamMb, totalRamMb,
230+
ru.ru_maxrss / 1024);
228231
// TODO: Report this result as a statement.
229232
if (freeRamMb < 200) {
230233
// Hard die if we are likely to run out of RAM, because
@@ -236,6 +239,50 @@ static void checkRam() {
236239
exit(1);
237240
}
238241
#endif
242+
#ifdef __APPLE__
243+
// Get total physical memory
244+
int64_t totalRamBytes = 0;
245+
size_t len = sizeof(totalRamBytes);
246+
if (sysctlbyname("hw.memsize", &totalRamBytes, &len, NULL, 0) != 0) {
247+
totalRamBytes = 0;
248+
}
249+
int totalRamMb = totalRamBytes / (1024 * 1024);
250+
251+
// Get VM statistics for free/available memory
252+
vm_size_t page_size;
253+
mach_port_t mach_port = mach_host_self();
254+
mach_msg_type_number_t count = sizeof(vm_statistics64_data_t) / sizeof(integer_t);
255+
vm_statistics64_data_t vm_stats;
256+
257+
int freeRamMb = 0;
258+
if (host_page_size(mach_port, &page_size) == KERN_SUCCESS &&
259+
host_statistics64(mach_port, HOST_VM_INFO64, (host_info64_t)&vm_stats, &count) == KERN_SUCCESS) {
260+
// Calculate available memory (free + inactive + purgeable)
261+
int64_t free_pages = vm_stats.free_count;
262+
int64_t inactive_pages = vm_stats.inactive_count;
263+
int64_t purgeable_pages = vm_stats.purgeable_count;
264+
int64_t available_bytes = (free_pages + inactive_pages + purgeable_pages) * page_size;
265+
freeRamMb = available_bytes / (1024 * 1024);
266+
}
267+
268+
// Check process's own RAM usage
269+
struct rusage ru;
270+
getrusage(RUSAGE_SELF, &ru);
271+
// Note: On macOS, ru_maxrss is in bytes, not kilobytes like Linux
272+
fprintf(stderr, "Check avail system RAM: %d MB / %d MB\n"
273+
"Check self RAM usage: %ld MB\n",
274+
freeRamMb, totalRamMb,
275+
ru.ru_maxrss / (1024 * 1024));
276+
277+
// TODO: Report this result as a statement.
278+
if (freeRamMb < 200) {
279+
// Hard die if we are likely to run out of RAM
280+
fprintf(stderr, "--------------------\n"
281+
"OUT OF RAM, EXITING.\n"
282+
"--------------------\n");
283+
exit(1);
284+
}
285+
#endif
239286
}
240287

241288
void *sysmonMain(void *ptr) {

0 commit comments

Comments
 (0)