Browse Source

sysconf: Support _SC_(AV)?PHYS_PAGES.

Do it by following the trail of the existing commented code, which
implemented it by calling get_phys_pages() and get_avphys_pages().
This patch implements these two functions, which are also glibc
extensions.

Some program/libraries (e.g. libuv) assumes that sysconf(_SC_PHYS_PAGES)
works on linux and never check for -1, thus they report an insane amount
of memory.

Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
Nicolas Cavallari 7 years ago
parent
commit
5e3d8e6682
2 changed files with 26 additions and 10 deletions
  1. 0 2
      include/sys/sysinfo.h
  2. 26 8
      libc/unistd/sysconf.c

+ 0 - 2
include/sys/sysinfo.h

@@ -56,13 +56,11 @@ extern int sysinfo (struct sysinfo *__info) __THROW;
 #define get_nprocs() (sysconf(_SC_NPROCESSORS_ONLN))
 
 
-#if 0
 /* Return number of physical pages of memory in the system.  */
 extern long int get_phys_pages (void) __THROW;
 
 /* Return number of available physical pages of memory in the system.  */
 extern long int get_avphys_pages (void) __THROW;
-#endif
 
 __END_DECLS
 

+ 26 - 8
libc/unistd/sysconf.c

@@ -43,6 +43,32 @@
 #include <dirent.h>
 #include "internal/parse_config.h"
 
+long int get_phys_pages(void)
+{
+	struct sysinfo si;
+	int ps = getpagesize();;
+
+	sysinfo(&si);
+
+	if (ps >= si.mem_unit)
+		return si.totalram / (ps / si.mem_unit);
+	else
+		return si.totalram * (si.mem_unit / ps);
+}
+
+long int get_avphys_pages(void)
+{
+	struct sysinfo si;
+	int ps = getpagesize();;
+
+	sysinfo(&si);
+
+	if (ps >= si.mem_unit)
+		return si.freeram / (ps / si.mem_unit);
+	else
+		return si.freeram * (si.mem_unit / ps);
+}
+
 static int nprocessors_onln(void)
 {
 	char **l = NULL;
@@ -747,18 +773,10 @@ long int sysconf(int name)
       RETURN_FUNCTION(nprocessors_onln());
 
     case _SC_PHYS_PAGES:
-#if 0
       RETURN_FUNCTION(get_phys_pages());
-#else
-      RETURN_NEG_1;
-#endif
 
     case _SC_AVPHYS_PAGES:
-#if 0
       RETURN_FUNCTION(get_avphys_pages());
-#else
-      RETURN_NEG_1;
-#endif
 
     case _SC_ATEXIT_MAX:
       return __UCLIBC_MAX_ATEXIT;