about summary refs log tree commit diff
path: root/sysdeps/unix/sysv/linux/getsysstats.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-06-22 10:32:07 -0400
committerUlrich Drepper <drepper@gmail.com>2011-06-22 10:32:07 -0400
commit84e2a551a72c79b020694bb327e33b6d71b09b63 (patch)
tree83c1518cab41c63afd51b67b23c7d29eab71418d /sysdeps/unix/sysv/linux/getsysstats.c
parent852eb34d5c56bc75bdd82327fcf310d98655f6b0 (diff)
downloadglibc-84e2a551a72c79b020694bb327e33b6d71b09b63.tar.gz
glibc-84e2a551a72c79b020694bb327e33b6d71b09b63.tar.xz
glibc-84e2a551a72c79b020694bb327e33b6d71b09b63.zip
Use a /sys/devices/system/cpu/online for _SC_NPROCESSORS_ONLN implementation
Diffstat (limited to 'sysdeps/unix/sysv/linux/getsysstats.c')
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c
index a13b6e3e37..b74774ffe8 100644
--- a/sysdeps/unix/sysv/linux/getsysstats.c
+++ b/sysdeps/unix/sysv/linux/getsysstats.c
@@ -161,20 +161,65 @@ __get_nprocs ()
   char *buffer_end = buffer + buffer_size;
   char *cp = buffer_end;
   char *re = buffer_end;
-  int result = 1;
 
 #ifdef O_CLOEXEC
   const int flags = O_RDONLY | O_CLOEXEC;
 #else
   const int flags = O_RDONLY;
 #endif
+  int fd = open_not_cancel_2 ("/sys/devices/system/cpu/online", flags);
+  char *l;
+  int result = 0;
+  if (fd != -1)
+    {
+      l = next_line (fd, buffer, &cp, &re, buffer_end);
+      if (l != NULL)
+	do
+	  {
+	    char *endp;
+	    unsigned long int n = strtoul (l, &endp, 10);
+	    if (l == endp)
+	      {
+		result = 0;
+		break;
+	      }
+
+	    unsigned long int m = n;
+	    if (*endp == '-')
+	      {
+		l = endp + 1;
+		m = strtoul (l, &endp, 10);
+		if (l == endp)
+		  {
+		    result = 0;
+		    break;
+		  }
+	      }
+
+	    result += m - n + 1;
+
+	    l = endp;
+	    while (l < re && isspace (*l))
+	      ++l;
+	  }
+	while (l < re);
+
+      close_not_cancel_no_status (fd);
+
+      if (result > 0)
+	goto out;
+    }
+
+  cp = buffer_end;
+  re = buffer_end;
+  result = 1;
+
   /* The /proc/stat format is more uniform, use it by default.  */
-  int fd = open_not_cancel_2 ("/proc/stat", flags);
+  fd = open_not_cancel_2 ("/proc/stat", flags);
   if (fd != -1)
     {
       result = 0;
 
-      char *l;
       while ((l = next_line (fd, buffer, &cp, &re, buffer_end)) != NULL)
 	/* The current format of /proc/stat has all the cpu* entries
 	   at the front.  We assume here that stays this way.  */
@@ -195,6 +240,7 @@ __get_nprocs ()
 	}
     }
 
+ out:
   cached_result = result;
   atomic_write_barrier ();
   timestamp = ts.tv_sec;