make-w32
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: GNU make 3.81beta4 released


From: Eli Zaretskii
Subject: Re: GNU make 3.81beta4 released
Date: Sat, 21 Jan 2006 22:19:02 +0200

> Date: Sat, 21 Jan 2006 21:05:22 +0200
> From: Eli Zaretskii <address@hidden>
> Cc: address@hidden
> 
> Sorry, my patch had a typo.  Please use this instead:

I must be smoking something today.  Please disregard the previous two
patches and use what's below; with it, I was able to repeatedly build
Emacs on Windows, and Make never hung nor crashed, although the
machine paged like heck.  I also verified that at no moment there was
more than 64 commands running, and that Make correctly stops launching
more commands when it reaches the limit.

Sorry for the mess I made.

2006-01-21  Eli Zaretskii  <address@hidden>

        * remake.c (update_goal_chain): Set g->changed instead of
        incrementing it, as it is only 8-bit wide, and could overflow if
        many commands got started in update_file.

        * w32/include/sub_proc.h: Add a prototype for process_used_slots.

        * w32/subproc/sub_proc.c: Change dimension of proc_array[] to
        MAXIMUM_WAIT_OBJECTS.
        (process_wait_for_any_private): Change dimension of handles[]
        array to MAXIMUM_WAIT_OBJECTS.
        (process_used_slots): New function.
        (process_register): Don't register more processes than the
        available number of slots. 
        (process_easy): Don't start new processes if all slots are used up.

        * job.c (load_too_high, start_waiting_jobs) [WINDOWS32]: If there
        are already more children than sub_proc.c can handle, behave as if
        the load were too high.
        (start_job_command): Fix a typo in error message when process_easy
        fails.

--- remake.c~   2005-12-07 15:33:38.000000000 +0200
+++ remake.c    2006-01-21 18:56:32.734375000 +0200
@@ -159,7 +159,7 @@ update_goal_chain (struct dep *goals)
              /* Set the goal's `changed' flag if any commands were started
                 by calling update_file above.  We check this flag below to
                 decide when to give an "up to date" diagnostic.  */
-             g->changed += commands_started - ocommands_started;
+             g->changed = commands_started > ocommands_started;
 
               /* If we updated a file and STATUS was not already 1, set it to
                  1 if updating failed, or to 0 if updating succeeded.  Leave

--- job.c~2     2006-01-14 14:00:00.921875000 +0200
+++ job.c       2006-01-21 21:37:14.812500000 +0200
@@ -1382,7 +1382,7 @@ start_job_command (struct child *child)
         int i;
         unblock_sigs();
         fprintf(stderr,
-          _("process_easy() failed failed to launch process (e=%ld)\n"),
+          _("process_easy() failed to launch process (e=%ld)\n"),
           process_last_err(hPID));
                for (i = 0; argv[i]; i++)
                  fprintf(stderr, "%s ", argv[i]);
@@ -1431,7 +1431,12 @@ start_waiting_job (struct child *c)
 
   /* If we are running at least one job already and the load average
      is too high, make this one wait.  */
-  if (!c->remote && job_slots_used > 0 && load_too_high ())
+  if (!c->remote
+      && ((job_slots_used > 0 && load_too_high ())
+#ifdef WINDOWS32
+         || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS)
+#endif
+         ))
     {
       /* Put this child on the chain of children waiting for the load average
          to go down.  */
@@ -1801,6 +1806,12 @@ load_too_high (void)
   double load, guess;
   time_t now;
 
+#ifdef WINDOWS32
+  /* sub_proc.c cannot wait for more than MAXIMUM_WAIT_OBJECTS children */
+  if (process_used_slots () >= MAXIMUM_WAIT_OBJECTS)
+    return 1;
+#endif
+
   if (max_load_average < 0)
     return 0;
 

--- w32/include/sub_proc.h~3    2005-02-10 04:10:58.000000000 +0200
+++ w32/include/sub_proc.h      2006-01-21 21:25:49.687500000 +0200
@@ -29,6 +29,7 @@
 EXTERN_DECL(void process_register, (HANDLE proc));
 EXTERN_DECL(HANDLE process_easy, (char** argv, char** env));
 EXTERN_DECL(BOOL process_kill, (HANDLE proc, int signal));
+EXTERN_DECL(int process_used_slots, (VOID_DECL));
 
 /* support routines */
 EXTERN_DECL(long process_errno, (HANDLE proc));

--- w32/subproc/sub_proc.c~2    2005-08-08 11:08:01.000000000 +0300
+++ w32/subproc/sub_proc.c      2006-01-21 21:37:14.906250000 +0200
@@ -31,7 +31,7 @@ typedef struct sub_process_t {
 } sub_process;
 
 /* keep track of children so we can implement a waitpid-like routine */
-static sub_process *proc_array[256];
+static sub_process *proc_array[MAXIMUM_WAIT_OBJECTS];
 static int proc_index = 0;
 static int fake_exits_pending = 0;
 
@@ -66,7 +66,7 @@ process_adjust_wait_state(sub_process* p
 static sub_process *
 process_wait_for_any_private(void)
 {
-       HANDLE handles[256];
+       HANDLE handles[MAXIMUM_WAIT_OBJECTS];
        DWORD retval, which;
        int i;
 
@@ -120,7 +120,17 @@ process_kill(HANDLE proc, int signal)
 void
 process_register(HANDLE proc)
 {
-       proc_array[proc_index++] = (sub_process *) proc;
+       if (proc_index < MAXIMUM_WAIT_OBJECTS)
+               proc_array[proc_index++] = (sub_process *) proc;
+}
+
+/*
+ * Return the number of processes that we are still waiting for.
+ */
+int
+process_used_slots(void)
+{
+       return proc_index;
 }
 
 /*
@@ -1169,6 +1179,10 @@ process_easy(
   HANDLE hErr;
   HANDLE hProcess;
 
+  if (proc_index >= MAXIMUM_WAIT_OBJECTS) {
+       DB (DB_JOBS, ("process_easy: All process slots used up\n"));
+       return INVALID_HANDLE_VALUE;
+  }
   if (DuplicateHandle(GetCurrentProcess(),
                       GetStdHandle(STD_INPUT_HANDLE),
                       GetCurrentProcess(),




reply via email to

[Prev in Thread] Current Thread [Next in Thread]