Factor out jobserver_active_p.

gcc/ChangeLog:

	* gcc.cc (driver::detect_jobserver): Remove and move to
	jobserver.h.
	* lto-wrapper.cc (jobserver_active_p): Likewise.
	(run_gcc): Likewise.
	* opts-jobserver.h: New file.
	* opts-common.cc (jobserver_info::jobserver_info): New function.
This commit is contained in:
Martin Liska 2022-08-09 13:59:32 +02:00
parent c16d9f78dc
commit 1270ccda70
4 changed files with 99 additions and 67 deletions

View File

@ -27,6 +27,7 @@ CC recognizes how to compile each input file by suffixes in the file names.
Once it knows which kind of compilation to perform, the procedure for
compilation is specified by a string called a "spec". */
#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
@ -43,6 +44,7 @@ compilation is specified by a string called a "spec". */
#include "opts.h"
#include "filenames.h"
#include "spellcheck.h"
#include "opts-jobserver.h"
@ -9178,38 +9180,9 @@ driver::final_actions () const
void
driver::detect_jobserver () const
{
/* Detect jobserver and drop it if it's not working. */
const char *makeflags = env.get ("MAKEFLAGS");
if (makeflags != NULL)
{
const char *needle = "--jobserver-auth=";
const char *n = strstr (makeflags, needle);
if (n != NULL)
{
int rfd = -1;
int wfd = -1;
bool jobserver
= (sscanf (n + strlen (needle), "%d,%d", &rfd, &wfd) == 2
&& rfd > 0
&& wfd > 0
&& is_valid_fd (rfd)
&& is_valid_fd (wfd));
/* Drop the jobserver if it's not working now. */
if (!jobserver)
{
unsigned offset = n - makeflags;
char *dup = xstrdup (makeflags);
dup[offset] = '\0';
const char *space = strchr (makeflags + offset, ' ');
if (space != NULL)
strcpy (dup + offset, space);
xputenv (concat ("MAKEFLAGS=", dup, NULL));
}
}
}
jobserver_info jinfo;
if (!jinfo.is_active && !jinfo.skipped_makeflags.empty ())
xputenv (jinfo.skipped_makeflags.c_str ());
}
/* Determine what the exit code of the driver should be. */

View File

@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
./ccCJuXGv.lto.ltrans.o
*/
#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
@ -49,6 +50,8 @@ along with GCC; see the file COPYING3. If not see
#include "lto-section-names.h"
#include "collect-utils.h"
#include "opts-diagnostic.h"
#include "opt-suggestions.h"
#include "opts-jobserver.h"
/* Environment variable, used for passing the names of offload targets from GCC
driver to lto-wrapper. */
@ -1336,35 +1339,6 @@ init_num_threads (void)
#endif
}
/* Test and return reason why a jobserver cannot be detected. */
static const char *
jobserver_active_p (void)
{
#define JS_PREFIX "jobserver is not available: "
#define JS_NEEDLE "--jobserver-auth="
const char *makeflags = getenv ("MAKEFLAGS");
if (makeflags == NULL)
return JS_PREFIX "%<MAKEFLAGS%> environment variable is unset";
const char *n = strstr (makeflags, JS_NEEDLE);
if (n == NULL)
return JS_PREFIX "%<" JS_NEEDLE "%> is not present in %<MAKEFLAGS%>";
int rfd = -1;
int wfd = -1;
if (sscanf (n + strlen (JS_NEEDLE), "%d,%d", &rfd, &wfd) == 2
&& rfd > 0
&& wfd > 0
&& is_valid_fd (rfd)
&& is_valid_fd (wfd))
return NULL;
else
return JS_PREFIX "cannot access %<" JS_NEEDLE "%> file descriptors";
}
/* Print link to -flto documentation with a hint message. */
void
@ -1422,7 +1396,6 @@ run_gcc (unsigned argc, char *argv[])
bool jobserver_requested = false;
int auto_parallel = 0;
bool no_partition = false;
const char *jobserver_error = NULL;
bool fdecoded_options_first = true;
vec<cl_decoded_option> fdecoded_options;
fdecoded_options.create (16);
@ -1653,14 +1626,14 @@ run_gcc (unsigned argc, char *argv[])
}
else
{
jobserver_error = jobserver_active_p ();
if (jobserver && jobserver_error != NULL)
jobserver_info jinfo;
if (jobserver && !jinfo.is_active)
{
/* Fall back to auto parallelism. */
jobserver = 0;
auto_parallel = 1;
}
else if (!jobserver && jobserver_error == NULL)
else if (!jobserver && jinfo.is_active)
{
parallel = 1;
jobserver = 1;
@ -1971,9 +1944,10 @@ cont:
if (nr > 1)
{
if (jobserver_requested && jobserver_error != NULL)
jobserver_info jinfo;
if (jobserver_requested && !jinfo.is_active)
{
warning (0, jobserver_error);
warning (0, jinfo.error_msg.c_str ());
print_lto_docs_link ();
}
else if (parallel == 0)

View File

@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "intl.h"
@ -25,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "options.h"
#include "diagnostic.h"
#include "spellcheck.h"
#include "opts-jobserver.h"
static void prune_options (struct cl_decoded_option **, unsigned int *);
@ -2005,3 +2007,42 @@ void prepend_xassembler_to_collect_as_options (const char *collect_as_options,
obstack_1grow (o, '\'');
}
}
jobserver_info::jobserver_info ()
{
/* Detect jobserver and drop it if it's not working. */
string js_needle = "--jobserver-auth=";
const char *envval = getenv ("MAKEFLAGS");
if (envval != NULL)
{
string makeflags = envval;
size_t n = makeflags.rfind (js_needle);
if (n != string::npos)
{
if (sscanf (makeflags.c_str () + n + js_needle.size (),
"%d,%d", &rfd, &wfd) == 2
&& rfd > 0
&& wfd > 0
&& is_valid_fd (rfd)
&& is_valid_fd (wfd))
is_active = true;
else
{
string dup = makeflags.substr (0, n);
size_t pos = makeflags.find (' ', n);
if (pos != string::npos)
dup += makeflags.substr (pos);
skipped_makeflags = "MAKEFLAGS=" + dup;
error_msg
= "cannot access %<" + js_needle + "%> file descriptors";
}
}
error_msg = "%<" + js_needle + "%> is not present in %<MAKEFLAGS%>";
}
else
error_msg = "%<MAKEFLAGS%> environment variable is unset";
if (!error_msg.empty ())
error_msg = "jobserver is not available: " + error_msg;
}

44
gcc/opts-jobserver.h Normal file
View File

@ -0,0 +1,44 @@
/* GNU make's jobserver related functionality.
Copyright (C) 2022 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>.
See dbgcnt.def for usage information. */
#ifndef GCC_JOBSERVER_H
#define GCC_JOBSERVER_H
using namespace std;
struct jobserver_info
{
/* Default constructor. */
jobserver_info ();
/* Error message if there is a problem. */
string error_msg = "";
/* Skipped MAKEFLAGS where --jobserver-auth is skipped. */
string skipped_makeflags = "";
/* File descriptor for reading used for jobserver communication. */
int rfd = -1;
/* File descriptor for writing used for jobserver communication. */
int wfd = -1;
/* Return true if jobserver is active. */
bool is_active = false;
};
#endif /* GCC_JOBSERVER_H */