A minor correction. I've missed a test for an error case. Updated patch can be found in the attachments.

Sven

--- make-4.2.1/configure.ac     2016-06-06 13:27:31.000000000 +0100
+++ make-4.2.1.1/configure.ac   2016-10-09 18:33:34.574257275 +0100
@@ -176,10 +176,30 @@
 AS_IF([test "$have_guile" = yes],
       [AC_DEFINE([HAVE_GUILE], [1], [Embed GNU Guile support])])
 
 AM_CONDITIONAL([HAVE_GUILE], [test "$have_guile" = yes])
 
+AC_CHECK_FUNCS[open close read lseek atoi]
+AC_CACHE_CHECK([for /proc/loadavg usability], [ac_cv_proc_loadavg],
+  [ac_cv_proc_loadavg=no
+   AC_RUN_IFELSE([AC_LANG_SOURCE([[#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+int main() {
+  int fd, i, n; char str[64];
+  fd = open("/proc/loadavg", O_RDONLY);
+  if (fd < 0 || read(fd, str, 64) < 0 || lseek(fd, 0, SEEK_SET) < 0) return 1;
+  for (str[63] = i = n = 0; i < 3 && n < 64; ++n) if (str[n] == ' ') ++i;
+  return i < 3 || atoi(&str[n]) < 1 || close(fd) < 0;}]])],
+                  [ac_cv_proc_loadavg=yes],
+                  [ac_cv_proc_loadavg=no],
+                  [ac_cv_proc_loadavg="no (cross-compiling)"])])
+AS_IF([test "$ac_cv_proc_loadavg" = yes],
+[ AC_DEFINE([HAVE_PROC_LOADAVG], [1],
+            [Define to 1 when /proc/loadavg exists and appears usable])
+])
+
 AC_FUNC_GETLOADAVG
 
 # AC_FUNC_GETLOADAVG is documented to set the NLIST_STRUCT value, but it
 # doesn't.  So, we will.
 
--- make-4.2.1/job.c    2016-05-21 21:22:32.000000000 +0100
+++ make-4.2.1.1/job.c  2016-10-09 20:02:43.047767201 +0100
@@ -1925,10 +1925,60 @@
 static int
 load_too_high (void)
 {
 #if defined(__MSDOS__) || defined(VMS) || defined(_AMIGA) || 
defined(__riscos__)
   return 1;
+#elif defined(HAVE_PROC_LOADAVG)
+  /* Read from /proc/loadavg and use the number of active running
+     tasks & threads to determine if we can start another process. */
+#define PROC_LOADAVG_SIZE 64
+  static int fd = -2;
+  char proc_loadavg[PROC_LOADAVG_SIZE];
+  int i, p;
+
+  if (max_load_average < 0 || fd == -1)
+    return 0;
+
+  if (fd == -2)
+    {
+      fd = open ("/proc/loadavg", O_RDONLY);
+      if (fd < 0)
+       {
+         perror_with_name (_("cannot open /proc/loadavg: "), "open");
+         fd = -1;
+         return 0;
+       }
+    }
+  if (read (fd, proc_loadavg, PROC_LOADAVG_SIZE) < 0)
+    {
+      perror_with_name (_("cannot read /proc/loadavg: "), "read");
+      close(fd);
+      fd = -1;
+      return 0;
+    }
+  if (lseek (fd, 0, SEEK_SET) < 0)
+    {
+      perror_with_name (_("cannot seek on /proc/loadavg: "), "lseek");
+      close(fd);
+      fd = -1;
+      return 0;
+    }
+  proc_loadavg[PROC_LOADAVG_SIZE-1] = '\0';
+  for (i = p = 0; i < 3 && p < PROC_LOADAVG_SIZE; ++p)
+    {
+      if (proc_loadavg[p] == ' ')
+       ++i;
+    }
+  if (i < 3)
+    {
+      errno = ENOTSUP;
+      perror_with_name (_("unsupported format of /proc/loadavg: "), 
"load_too_high");
+      close (fd);
+      fd = -1;
+      return 0;
+    }
+  return max_load_average < (double) atoi (&proc_loadavg[p]);
 #else
   static double last_sec;
   static time_t last_now;
   double load, guess;
   time_t now;
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
https://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to