aboutsummaryrefslogtreecommitdiff
path: root/libgfortran/runtime/stop.c
diff options
context:
space:
mode:
authorJanne Blomqvist <jb@gcc.gnu.org>2018-09-21 21:12:59 +0300
committerJanne Blomqvist <jb@gcc.gnu.org>2018-09-21 21:12:59 +0300
commitedaaef601d0d6d263fba87b42d6d04c99dd23dba (patch)
tree1eae37a9045b327759b9ea32319467c34314ddb6 /libgfortran/runtime/stop.c
parent5b4dd0158308d1a3effffd6316f1b39fdd1ad120 (diff)
downloadgcc-edaaef601d0d6d263fba87b42d6d04c99dd23dba.zip
gcc-edaaef601d0d6d263fba87b42d6d04c99dd23dba.tar.gz
gcc-edaaef601d0d6d263fba87b42d6d04c99dd23dba.tar.bz2
Use vectored writes when reporting errors and warnings.
When producing error and warning messages, libgfortran writes a message by using many system calls. By using vectored writes (the POSIX writev function) when available and feasible to use without major surgery, we reduce the chance that output gets intermingled with other output to stderr. In practice, this is done by introducing a new function estr_writev in addition to the existing estr_write. In order to use this, the old st_vprintf is removed, replaced by direct calls of vsnprintf, allowing more message batching. Regtested on x86_64-pc-linux-gnu. libgfortran/ChangeLog: 2018-09-21 Janne Blomqvist <jb@gcc.gnu.org> * config.h.in: Regenerated. * configure: Regenerated. * configure.ac: Check for writev and sys/uio.h. * libgfortran.h: Include sys/uio.h. (st_vprintf): Remove prototype. (struct iovec): Define if not available. (estr_writev): New prototype. * runtime/backtrace.c (error_callback): Use estr_writev. * runtime/error.c (ST_VPRINTF_SIZE): Remove. (estr_writev): New function. (st_vprintf): Remove. (gf_vsnprintf): New function. (ST_ERRBUF_SIZE): New macro. (st_printf): Use vsnprintf. (os_error): Use estr_writev. (runtime_error): Use vsnprintf and estr_writev. (runtime_error_at): Likewise. (runtime_warning_at): Likewise. (internal_error): Use estr_writev. (generate_error_common): Likewise. (generate_warning): Likewise. (notify_std): Likewise. * runtime/pause.c (pause_string): Likewise. * runtime/stop.c (report_exception): Likewise. (stop_string): Likewise. (error_stop_string): Likewise. From-SVN: r264487
Diffstat (limited to 'libgfortran/runtime/stop.c')
-rw-r--r--libgfortran/runtime/stop.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/libgfortran/runtime/stop.c b/libgfortran/runtime/stop.c
index 1e6dd8c..4833e7b 100644
--- a/libgfortran/runtime/stop.c
+++ b/libgfortran/runtime/stop.c
@@ -29,6 +29,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <unistd.h>
#endif
+#include <string.h>
/* Fortran 2008 demands: If any exception (14) is signaling on that image, the
processor shall issue a warning indicating which exceptions are signaling;
@@ -40,7 +41,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
static void
report_exception (void)
{
- int set_excepts;
+ struct iovec iov[8];
+ int set_excepts, iovcnt = 1;
if (!compile_options.fpe_summary)
return;
@@ -49,33 +51,62 @@ report_exception (void)
if ((set_excepts & compile_options.fpe_summary) == 0)
return;
- estr_write ("Note: The following floating-point exceptions are signalling:");
+ iov[0].iov_base = (char*) "Note: The following floating-point exceptions are signalling:";
+ iov[0].iov_len = strlen (iov[0].iov_base);
if ((compile_options.fpe_summary & GFC_FPE_INVALID)
&& (set_excepts & GFC_FPE_INVALID))
- estr_write (" IEEE_INVALID_FLAG");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_INVALID_FLAG";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
if ((compile_options.fpe_summary & GFC_FPE_ZERO)
&& (set_excepts & GFC_FPE_ZERO))
- estr_write (" IEEE_DIVIDE_BY_ZERO");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_DIVIDE_BY_ZERO";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
if ((compile_options.fpe_summary & GFC_FPE_OVERFLOW)
&& (set_excepts & GFC_FPE_OVERFLOW))
- estr_write (" IEEE_OVERFLOW_FLAG");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_OVERFLOW_FLAG";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
if ((compile_options.fpe_summary & GFC_FPE_UNDERFLOW)
&& (set_excepts & GFC_FPE_UNDERFLOW))
- estr_write (" IEEE_UNDERFLOW_FLAG");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_UNDERFLOW_FLAG";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
if ((compile_options.fpe_summary & GFC_FPE_DENORMAL)
&& (set_excepts & GFC_FPE_DENORMAL))
- estr_write (" IEEE_DENORMAL");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_DENORMAL";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
if ((compile_options.fpe_summary & GFC_FPE_INEXACT)
&& (set_excepts & GFC_FPE_INEXACT))
- estr_write (" IEEE_INEXACT_FLAG");
+ {
+ iov[iovcnt].iov_base = (char*) " IEEE_INEXACT_FLAG";
+ iov[iovcnt].iov_len = strlen (iov[iovcnt].iov_base);
+ iovcnt++;
+ }
+
+ iov[iovcnt].iov_base = (char*) "\n";
+ iov[iovcnt].iov_len = 1;
+ iovcnt++;
- estr_write ("\n");
+ estr_writev (iov, iovcnt);
}
@@ -106,9 +137,14 @@ stop_string (const char *string, size_t len, bool quiet)
report_exception ();
if (string)
{
- estr_write ("STOP ");
- (void) write (STDERR_FILENO, string, len);
- estr_write ("\n");
+ struct iovec iov[3];
+ iov[0].iov_base = (char*) "STOP ";
+ iov[0].iov_len = strlen (iov[0].iov_base);
+ iov[1].iov_base = (char*) string;
+ iov[1].iov_len = len;
+ iov[2].iov_base = (char*) "\n";
+ iov[2].iov_len = 1;
+ estr_writev (iov, 3);
}
}
exit (0);
@@ -128,10 +164,15 @@ error_stop_string (const char *string, size_t len, bool quiet)
{
if (!quiet)
{
+ struct iovec iov[3];
report_exception ();
- estr_write ("ERROR STOP ");
- (void) write (STDERR_FILENO, string, len);
- estr_write ("\n");
+ iov[0].iov_base = (char*) "ERROR STOP ";
+ iov[0].iov_len = strlen (iov[0].iov_base);
+ iov[1].iov_base = (char*) string;
+ iov[1].iov_len = len;
+ iov[2].iov_base = (char*) "\n";
+ iov[2].iov_len = 1;
+ estr_writev (iov, 3);
}
exit_error (1);
}