// 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 }