[Date Prev][Date Next][Thread Prev][Thread Next][Thread Index]
Re: [XaraXtreme-dev] [patch] Have implemented a Linux port of GetMemoryStatus ("Function to find available RAM")
- From: "Israel G. Lugo" <ilugo@xxxxxxxxxxxxxxxxxx>
- Date: Sat, 27 May 2006 23:23:33 +0100
- Subject: Re: [XaraXtreme-dev] [patch] Have implemented a Linux port of GetMemoryStatus ("Function to find available RAM")
Hello,
Alex Bligh wrote:
> Israel,
>
> Thanks for this. I will have a look in more detail in the morning but
> a couple of comments:
Sure, glad to be of help :)
> 1. (perhaps based on what Phil gave you) it seems to me that
> we are doing #ifdef MSW, #elif #WXMAC, #else (assume Linux)
> and then processing a /proc file. Well, that means FreeBSD
> etc. will fail to compile because hey aren't Mac or MSW.
> I think we should instead test for MSW (and use that if so),
> then for Linux (explicitly) and use your code, then if that
> fails, fail for Mac, FreeBSD etc. as well. That's better than
> trying to open files that don't exist on FreeBSD. (I think
> the /proc file is not going to exist on FreeBSD etc. - right
> Vasil?)
I agree that an explicit test for Linux would be advantageous, since
this code is only really guaranteed to function (at runtime) on Linux
(BSD does not, to my knowledge, have a /proc/meminfo interface as Linux
does, although I believe it is possible to install some compatibility
packages to simulate some Linux features).
However, the code *will* definitely compile and run on any
ANSI-compliant system; in particular, it will compile and run on a BSD
system, Mac, and so on. The code can still be used as-is without
breaking anything, until a specific Linux check is added (and different
implementations are made for the non-Linux platforms).
Naturally, for non-Linux platforms, if the /proc/meminfo file does not
exist, the code will not be able to extract the relevant memory
information; however, it still falls back to a guess like the original
version did (please see below for more on that).
> 2. Minor nit: if the /proc file fails to open, it seems to me
> that haveMemTotal and haveMemFree will be unitialized. They
> should I think be initialized to zero, so if the open fails,
> the appropriate default routines are called.
You are absolutely correct, it would make no sense otherwise. It was a
minor oversight on my part, I'm quite sure I had them initialized to 0
at some point but must have rewritten that line and forgot to put the
initializations back in. Clearly they need to be set to 0 upon
declaration, so that the verification below works and is able to fall
back to a 512MB 50% free guess (I took those values from the original code).
I am sending the revised patch, with the variables initialized this time
(that's the only difference).
Regards,
Israel
Index: memory.cpp
===================================================================
--- memory.cpp (revision 1199)
+++ memory.cpp (working copy)
@@ -118,6 +118,10 @@
#include "ralphcri.h"
#endif
+#if !defined(__WXMSW__) && !defined(__WXMAC__)
+# include <stdio.h>
+#endif
+
DECLARE_SOURCE("$Revision$");
@@ -1023,10 +1027,43 @@
if (pLoadPercent) *pLoadPercent = memStatus.dwMemoryLoad;
if (pPhysRam) *pPhysRam = memStatus.dwTotalPhys;
}
-#else
- PORTNOTETRACE("other", "GetMemoryStatus is not implemented on this architecture");
+#elif defined(__WXMAC__)
+ PORTNOTETRACE("other", "GetMemoryStatus is not implemented for WXMAC");
if (pPhysRam) *pPhysRam = 512L * 1024 * 1024; // Guess 512M
if (pLoadPercent) *pLoadPercent = 50; // Guess 50% free
+#else
+ /* Linux: read memory information from the kernel's /proc/meminfo interface */
+ FILE *fp;
+ unsigned long memTotalKb, memFreeKb;
+ int haveMemTotal = 0, haveMemFree = 0;
+ char lineBuf[256];
+
+ fp = fopen("/proc/meminfo", "r");
+
+ if (fp != NULL)
+ {
+ while (!haveMemTotal || !haveMemFree)
+ {
+ if (fgets(lineBuf, 256, fp) == NULL)
+ break;
+
+ if (sscanf(lineBuf, "MemTotal: %lu", &memTotalKb) == 1)
+ haveMemTotal = 1;
+ if (sscanf(lineBuf, "MemFree: %lu", &memFreeKb) == 1)
+ haveMemFree = 1;
+ }
+ fclose(fp);
+ }
+
+ if (!haveMemTotal)
+ memTotalKb = 512UL * 1024; /* guess 512MB */
+ if (!haveMemFree)
+ memFreeKb = memTotalKb / 2; /* guess 50% free */
+
+ if (pPhysRam != NULL)
+ *pPhysRam = (UINT64)memTotalKb * 1024;
+ if (pLoadPercent != NULL)
+ *pLoadPercent = (UINT32)(100UL - ((memFreeKb * 100UL) / memTotalKb));
#endif
}