help-make
[Top][All Lists]
Advanced

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

Re: Using GNU make jobserver from GCC


From: Jan Hubicka
Subject: Re: Using GNU make jobserver from GCC
Date: Mon, 19 May 2014 06:39:25 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

> On Mon, 2014-05-19 at 00:48 +0200, Jan Hubicka wrote:
> > I wonder if thre can be any additional support from GNU's make to make
> > "+" unnecesary and if it would be possible to spearate client side of
> > GNU Make's jobserver into separate file that can be spossibly shared
> > in between GNU make and GCC - perhaps via liberty library?
> 
> For the second question, the short answer is "no, not right now".
> Unfortunately the jobserver feature is sort of embedded into make and
> not easily extracted.  That doesn't mean it couldn't be extracted, but
> as it's written today it's not entirely clear what the higher-level
> interface would need to be.  Some investigation would need to be
> undertaken.  However, the POSIX-based interface for jobserver support is
> pretty trivial and I'd be surprised if it's worthwhile to extract it: it
> just reads a byte and writes a byte.  If you want to try to allow for
> jobserver on Windows as well, which uses a very different method of
> tracking jobs than the POSIX ports, that would be another story.

Since GCC supports Windows, too, I would love to have generic solution.  To be
honest, GCC currently uses fork for the parallelism that probalby won't make
Windows fly, but threaded implementation is possible, too (just extra work to
make streaming thread-safe).  The main loop is pretty simple:

static void
stream_out (char *temp_filename, lto_symtab_encoder_t encoder, bool last)
{
#ifdef HAVE_WORKING_FORK
  static int nruns;

  if (lto_parallelism <= 1)
    {
      do_stream_out (temp_filename, encoder);
      return;
    }

  /* Do not run more than LTO_PARALLELISM streamings
     FIXME: we ignore limits on jobserver.  */
  if (lto_parallelism > 0 && nruns >= lto_parallelism)
    {
      wait_for_child ();
      nruns --;
    }
  /* If this is not the last parallel partition, execute new
     streaming process.  */
  if (!last)
    {
      pid_t cpid = fork ();

      if (!cpid)
        {
          setproctitle ("lto1-wpa-streaming");
          do_stream_out (temp_filename, encoder);
          exit (0);
        }
      /* Fork failed; lets do the job ourseleves.  */
      else if (cpid == -1)
        do_stream_out (temp_filename, encoder);
      else
        nruns++;
    }
  /* Last partition; stream it and wait for all children to die.  */
  else
    {
      int i;
      do_stream_out (temp_filename, encoder);
      for (i = 0; i < nruns; i++)
        wait_for_child ();
    }
}

where wait_for_child is:

/* Wait for forked process and signal errors.  */
#ifdef HAVE_WORKING_FORK
static void
wait_for_child ()
{
  int status;
  do
    {
#ifndef WCONTINUED
#define WCONTINUED 0
#endif
      int w = waitpid (0, &status, WUNTRACED | WCONTINUED);
      if (w == -1)
        fatal_error ("waitpid failed");

      if (WIFEXITED (status) && WEXITSTATUS (status))
        fatal_error ("streaming subprocess failed");
      else if (WIFSIGNALED (status))
        fatal_error ("streaming subprocess was killed by signal");
    }
  while (!WIFEXITED (status) && !WIFSIGNALED (status));
}
#endif

Ideally the first loop calling wait_for_child can be replaced by libiberty
function that will just sleep until next job is available.
> 
> For the first question, the reason "+" is needed is that some programs
> that make invokes do not behave well if there are extra file descriptors
> open (other than stdin, stdout, stderr) when they are invoked.  As a
> result, make is careful to close all open file descriptors other than 0,
> 1, and 2 before invoking any program that does not need them.  Recursive
> makes need them, obviously, to support the jobserver, so any command
> that contains $(MAKE) or uses the "+" token keeps the file descriptors.
> Any other program has them closed before being invoked.
> 
> Yes, these tools are broken.  However, they do, or at least did, exist.
> I'm not against providing a way to make this work but it would need to
> be well-designed.

Hmm, I wonder if we can't pass necessary info in environment var to re-connect
to jobserver?  I suppose adding gcc to the list of commands that keeps
descriptors is not the coolest idea...

Honza



reply via email to

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