// return free and total system memory in bytes
uint64_t I_GetFreeMem(uint64_t *total)
{
#ifdef LINUX
// LINUX covers all the unix-type OS's.
#ifdef FREEBSD
struct vmmeter sum;
kvm_t *kd;
struct nlist namelist[]= {
#define X_SUM 0
{"_cnt"},
{ NULL }
};
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
goto guess;
if (kvm_nlist(kd, namelist) != 0)
{
kvm_close (kd);
goto guess;
}
if (kvm_read(kd,namelist[X_SUM].n_value ,&sum, sizeof(sum)) != sizeof(sum))
{
kvm_close (kd);
goto guess;
}
kvm_close (kd);
*total = sum.v_page_count * sum.v_page_size;
return sum.v_free_count * sum.v_page_size;
#elif defined(SOLARIS)
goto guess;
#else
// Actual Linux
#define MEMINFO_FILE "/proc/meminfo"
#define MEMTOTAL "MemTotal:"
#define MEMFREE "MemFree:"
char buf[1024];
char *memTag;
uint64_t freeKBytes;
uint64_t totalKBytes;
int meminfo_fd = open(MEMINFO_FILE, O_RDONLY);
int n = read(meminfo_fd, buf, 1023);
close(meminfo_fd);
if(n<0)
goto guess;
buf[n] = '\0';
if(NULL == (memTag = strstr(buf, MEMTOTAL)))
goto guess;
memTag += sizeof(MEMTOTAL);
totalKBytes = atoi(memTag);
if(NULL == (memTag = strstr(buf, MEMFREE)))
goto guess;
memTag += sizeof(MEMFREE);
freeKBytes = atoi(memTag);
*total = totalKBytes << 10;
return freeKBytes << 10;
guess:
// make a conservative guess
*total = 32 << 20;
return 32 << 20;
#endif // Unix flavors
#elif defined(WIN32)
// windows
#if defined(WIN_LARGE_MEM) && defined( _WIN32_WINNT ) && (_WIN32_WINNT >= 0x0500)
// large memory status, only in newer libraries
MEMORYSTATUSEX statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
*total = statex.ullTotalPhys;
return statex.ullAvailPhys;
#else
// older memory status
MEMORYSTATUS statex;
statex.dwLength = sizeof(statex);
GlobalMemoryStatus(&statex);
*total = statex.dwTotalPhys;
return statex.dwAvailPhys;
#endif
#else
// unknown
// make a conservative guess
*total = 32 << 20;
return 32 << 20;
#endif
}
Comments