1717#include < limits>
1818#include < vector>
1919#include < sys/resource.h>
20+ #if defined(__APPLE__)
21+ #include < sys/sysctl.h>
22+ #elif defined(__linux__)
23+ #include < sys/sysinfo.h>
24+ #elif defined(_WIN32)
25+ #include < windows.h>
26+ #endif
2027
2128// Timing helper — writes to a dedicated file, not captured by the ctest driver.
2229static std::ofstream &timingLog ()
@@ -42,6 +49,59 @@ static double peak_rss_mb()
4249 return ru.ru_maxrss / 1024.0 ;
4350#endif
4451}
52+ // Returns the available (free) physical memory in MB.
53+ static double available_mem_mb ()
54+ {
55+ #if defined(__APPLE__)
56+ uint64_t memsize = 0 ;
57+ size_t len = sizeof (memsize);
58+ // vm.pagesize * vm_stat free pages gives available memory
59+ int pagesize = 0 ;
60+ size_t plen = sizeof (pagesize);
61+ sysctlbyname (" hw.pagesize" , &pagesize, &plen, nullptr , 0 );
62+ // Use hw.memsize for total; approximate available via sysctl vm.page_free_count
63+ uint64_t pagefree = 0 ;
64+ size_t pflen = sizeof (pagefree);
65+ if (sysctlbyname (" vm.page_free_count" , &pagefree, &pflen, nullptr , 0 ) == 0 && pagesize > 0 )
66+ return (pagefree * (double )pagesize) / (1024.0 * 1024.0 );
67+ // fallback: total physical memory
68+ sysctlbyname (" hw.memsize" , &memsize, &len, nullptr , 0 );
69+ return memsize / (1024.0 * 1024.0 );
70+ #elif defined(__linux__)
71+ struct sysinfo si;
72+ if (sysinfo (&si) == 0 )
73+ return (si.freeram * (double )si.mem_unit ) / (1024.0 * 1024.0 );
74+ return -1.0 ;
75+ #else
76+ return -1.0 ;
77+ #endif
78+ }
79+
80+ // Returns the available (free) swap space in MB.
81+ static double available_swap_mb ()
82+ {
83+ #if defined(__APPLE__)
84+ struct xsw_usage swapinfo;
85+ size_t len = sizeof (swapinfo);
86+ if (sysctlbyname (" vm.swapusage" , &swapinfo, &len, nullptr , 0 ) == 0 )
87+ return swapinfo.xsu_avail / (1024.0 * 1024.0 );
88+ return -1.0 ;
89+ #elif defined(__linux__)
90+ struct sysinfo si;
91+ if (sysinfo (&si) == 0 )
92+ return (si.freeswap * (double )si.mem_unit ) / (1024.0 * 1024.0 );
93+ return -1.0 ;
94+ #elif defined(_WIN32)
95+ MEMORYSTATUSEX ms;
96+ ms.dwLength = sizeof (ms);
97+ if (GlobalMemoryStatusEx (&ms))
98+ return ms.ullAvailPageFile / (1024.0 * 1024.0 );
99+ return -1.0 ;
100+ #else
101+ return -1.0 ;
102+ #endif
103+ }
104+
45105#define TIME_SUBTEST (timing, label, call ) \
46106 do { \
47107 std::cerr << (label) << " ...\n " ; \
@@ -622,10 +682,17 @@ int testMapObjectLargeOffset()
622682// -----------------------------------------------------------------------
623683// Entry point
624684// -----------------------------------------------------------------------
625- int testLargeCollection (bool timing = false )
685+ int testLargeCollection (bool timing = false , bool memoryCheck = false )
626686{
627687 int errors = 0 ;
628688
689+ if (memoryCheck) {
690+ std::cerr << " Available memory at start: " << available_mem_mb () << " MB\n " ;
691+ double swap = available_swap_mb ();
692+ if (swap >= 0.0 )
693+ std::cerr << " Available swap at start: " << swap << " MB\n " ;
694+ }
695+
629696 std::vector<float > sharedLargeFloats;
630697 TIME_SUBTEST (timing, " testDirectNumerical" , testDirectNumerical (sharedLargeFloats));
631698 TIME_SUBTEST (timing, " testDirectStruct" , testDirectStruct (timing));
0 commit comments