wxGetFreeMemory workaround for Linux and BSD ports

If you have a cool piece of software to share, but you are not hosting it officially yet, please dump it in here. If you have code snippets that are useful, please donate!
Post Reply
wxCod3r
Earned a small fee
Earned a small fee
Posts: 13
Joined: Fri Jan 14, 2005 6:03 am
Location: USA

wxGetFreeMemory workaround for Linux and BSD ports

Post by wxCod3r »

wxGetFreeMemory isn't implemented as of 2.5.3 for FreeBSD and other BSD variants, and the Linux implementation reads /proc/meminfo and doesn't return correct results due to the variations in the format of /proc/meminfo.

Here's a simple workaround which should work on most supported platforms.

Code: Select all


void wxGetMemoryInfo(long *memTotal, long *memUsed, long *memFree)
{
   // zero everything to start with
   *(memTotal) = *(memUsed) = *(memFree) = 0;
#if defined(__WINDOWS__)
    MEMORYSTATUS memStatus;
    memStatus.dwLength = sizeof(MEMORYSTATUS);
    GlobalMemoryStatus(&memStatus);
    *(memTotal) = memStatus.dwTotalPhys;
    *(memUsed) = memStatus.dwMemoryLoad;
    *(memFree) = memStatus.dwAvailPhys;
#elif defined(__UNIX__) || defined(__UNIX_LIKE__)
#  if !defined(__BSD__) && !defined(__DARWIN__)

   // this should be fine on most unix-like platforms
   // note: it doesn't report memory dedicated to the kernel
   //       but is otherwise, reasonably accurate.
   //       e.g. 256MiB installed, but reports 248MiB
    long page_size = sysconf(_SC_PAGESIZE);
    *(memTotal) = sysconf(_SC_PHYS_PAGES)*page_size;
    *(memFree)  = sysconf(_SC_AVPHYS_PAGES)*page_size;
    *(memUsed)  = *(memTotal) - *(memFree);

#   elif defined(__BSD__) || defined(__DARWIN__)

    long total_pages, free_pages, page_size;

    size_t size = sizeof(long);
    if(sysctlbyname("hw.pagesize", &page_size, &size, 0, 0) != 0 ||
       size != sizeof(long)) return;
    
    size = sizeof(long);
    if(sysctlbyname("vm.stats.vm.v_page_count", &total_pages, &size, 0, 0) != 0 ||
       size != sizeof(long)) return;

    // this may not work under FreeBSD?
    size = sizeof(long);
    if(sysctlbyname("vm.stats.vm.v_free_count", &free_pages, &size, 0, 0) != 0 ||
       size != sizeof(long)) return;

    *(memTotal) = page_size * total_pages;
    *(memFree) = page_size * free_pages;
    *(memUsed) = page_size * (total_pages - free_pages);
#   endif
#else
    // not implemented but defined for
    // portability - values were nulled above
#endif
}
Hope it was useful...
Cheers!
Last edited by wxCod3r on Thu Jan 20, 2005 10:54 pm, edited 1 time in total.
User avatar
Ryan Norton
Moderator
Moderator
Posts: 1319
Joined: Mon Aug 30, 2004 6:01 pm

Re: wxGetFreeMemory workaround for Linux and BSD ports

Post by Ryan Norton »

I should note that Vadim said he would accept a patch to function with an implementation like this :).
Avi
Super wx Problem Solver
Super wx Problem Solver
Posts: 398
Joined: Mon Aug 30, 2004 9:27 pm
Location: Tel-Aviv, Israel

Post by Avi »

Yeah, wxCod3r, it would be great if you could create a patch (.diff) and post it in SF.net's patches tracker: http://sourceforge.net/tracker/?group_i ... tid=309863 :)

Thanks for the good work!
Post Reply