aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <amylaar@cygnus.co.uk>2000-01-26 22:27:31 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2000-01-26 22:27:31 +0000
commite09d24ffb12aff104ba1f584c420445aac4c1873 (patch)
treea0a5ab7d409b5f49313a069ba391408c5b9a49b2 /gcc
parent628d74de0e60a79f0b0e745a790c573663315f9e (diff)
downloadgcc-e09d24ffb12aff104ba1f584c420445aac4c1873.zip
gcc-e09d24ffb12aff104ba1f584c420445aac4c1873.tar.gz
gcc-e09d24ffb12aff104ba1f584c420445aac4c1873.tar.bz2
calls.c (special_function_p): New argument fork_or_exec.
gcc: * calls.c (special_function_p): New argument fork_or_exec. (expand_call): When profile_arc_flag is set and the function is in the fork_or_exec group, call __bb_fork_func first. * libgcc2.c, _bb module (__bb_fork_func): New function. (__bb_exit_func): If fcntl F_SETLKW is available, use it to lock output file. * config/svr4.h (TARGET_HAS_F_SETLKW): Define. * tree.h (special_function_p): Update prototype. gcc/cp: * cp/optimize.c (calls_setjmp_r): Supply new argument to special_function_p. From-SVN: r31635
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/svr4.h1
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/optimize.c4
-rw-r--r--gcc/libgcc2.c94
-rw-r--r--gcc/tm.texi8
-rw-r--r--gcc/tree.h2
7 files changed, 109 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 43797c2..6801c88 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+Wed Jan 26 22:19:14 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * calls.c (special_function_p): New argument fork_or_exec.
+ (expand_call): When profile_arc_flag is set and the function
+ is in the fork_or_exec group, call __bb_fork_func first.
+ * libgcc2.c, _bb module (__bb_fork_func): New function.
+ (__bb_exit_func): If fcntl F_SETLKW is available, use it to lock
+ output file.
+ * config/svr4.h (TARGET_HAS_F_SETLKW): Define.
+ * tree.h (special_function_p): Update prototype.
+
2000-01-26 Richard Henderson <rth@cygnus.com>
* alpha.c (alpha_split_tfmode_pair): New.
diff --git a/gcc/config/svr4.h b/gcc/config/svr4.h
index a1ebaa6..23911d9 100644
--- a/gcc/config/svr4.h
+++ b/gcc/config/svr4.h
@@ -235,3 +235,4 @@ Boston, MA 02111-1307, USA.
to support ANSI C. */
/* #define MULTIBYTE_CHARS */
+#define TARGET_HAS_F_SETLKW
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7cd0cb4..2834ebb 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+Wed Jan 26 22:19:14 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * cp/optimize.c (calls_setjmp_r): Supply new argument
+ to special_function_p.
+
2000-01-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* call.c: PROTO -> PARAMS.
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index d97749d..60ccbbd 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -732,6 +732,7 @@ calls_setjmp_r (tp, walk_subtrees, data)
{
int setjmp_p;
int longjmp_p;
+ int fork_or_exec_p;
int malloc_p;
int alloca_p;
@@ -739,7 +740,8 @@ calls_setjmp_r (tp, walk_subtrees, data)
if (TREE_CODE (*tp) != FUNCTION_DECL)
return NULL_TREE;
- special_function_p (*tp, &setjmp_p, &longjmp_p, &malloc_p, &alloca_p);
+ special_function_p (*tp, &setjmp_p, &longjmp_p, &fork_or_exec_p, &malloc_p,
+ &alloca_p);
return setjmp_p ? *tp : NULL_TREE;
}
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 5ccd679..de14051 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1,6 +1,7 @@
/* More subroutines needed by GCC output code on some machines. */
/* Compile this one with gcc. */
-/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 92, 93, 94, 95, 96, 97, 98, 1999, 2000
+ Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -1563,6 +1564,10 @@ char *ctime ();
#include "gbl-ctors.h"
#include "gcov-io.h"
#include <string.h>
+#ifdef TARGET_HAS_F_SETLKW
+#include <fcntl.h>
+#include <errno.h>
+#endif
static struct bb *bb_head;
@@ -1606,13 +1611,64 @@ __bb_exit_func (void)
for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
{
- /* If the file exists, and the number of counts in it is the same,
- then merge them in. */
-
- if ((da_file = fopen (ptr->filename, "rb")) != 0)
+ int firstchar;
+
+ /* Make sure the output file exists -
+ but don't clobber exiting data. */
+ if ((da_file = fopen (ptr->filename, "a")) != 0)
+ fclose (da_file);
+
+ /* Need to re-open in order to be able to write from the start. */
+ da_file = fopen (ptr->filename, "r+b");
+ /* Some old systems might not allow the 'b' mode modifier.
+ Therefore, try to open without it. This can lead to a race
+ condition so that when you delete and re-create the file, the
+ file might be opened in text mode, but then, you shouldn't
+ delete the file in the first place. */
+ if (da_file == 0)
+ da_file = fopen (ptr->filename, "r+");
+ if (da_file == 0)
+ {
+ fprintf (stderr, "arc profiling: Can't open output file %s.\n",
+ ptr->filename);
+ continue;
+ }
+
+ /* After a fork, another process might try to read and/or write
+ the same file simultanously. So if we can, lock the file to
+ avoid race conditions. */
+#if defined (TARGET_HAS_F_SETLKW)
+ {
+ struct flock s_flock;
+
+ s_flock.l_type = F_WRLCK;
+ s_flock.l_whence = SEEK_SET;
+ s_flock.l_start = 0;
+ s_flock.l_len = 1;
+ s_flock.l_pid = getpid ();
+
+ while (fcntl (fileno (da_file), F_SETLKW, &s_flock)
+ && errno == EINTR);
+ }
+#endif
+
+ /* If the file is not empty, and the number of counts in it is the
+ same, then merge them in. */
+ firstchar = fgetc (da_file);
+ if (firstchar == EOF)
+ {
+ if (ferror (da_file))
+ {
+ fprintf (stderr, "arc profiling: Can't read output file ");
+ perror (ptr->filename);
+ }
+ }
+ else
{
long n_counts = 0;
+ if (ungetc (firstchar, da_file) == EOF)
+ rewind (da_file);
if (__read_long (&n_counts, da_file, 8) != 0)
{
fprintf (stderr, "arc profiling: Can't read output file %s.\n",
@@ -1638,17 +1694,10 @@ __bb_exit_func (void)
}
}
- if (fclose (da_file) == EOF)
- fprintf (stderr, "arc profiling: Error closing output file %s.\n",
- ptr->filename);
- }
- if ((da_file = fopen (ptr->filename, "wb")) == 0)
- {
- fprintf (stderr, "arc profiling: Can't open output file %s.\n",
- ptr->filename);
- continue;
}
+ rewind (da_file);
+
/* ??? Should first write a header to the file. Preferably, a 4 byte
magic number, 4 bytes containing the time the program was
compiled, 4 bytes containing the last modification time of the
@@ -1826,6 +1875,23 @@ __bb_init_func (struct bb *blocks)
bb_head = blocks;
}
+/* Called before fork or exec - write out profile information gathered so
+ far and reset it to zero. This avoids duplication or loss of the
+ profile information gathered so far. */
+void
+__bb_fork_func (void)
+{
+ struct bb *ptr;
+
+ __bb_exit_func ();
+ for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next)
+ {
+ long i;
+ for (i = ptr->ncounts - 1; i >= 0; i--)
+ ptr->counts[i] = 0;
+ }
+}
+
#ifndef MACHINE_STATE_SAVE
#define MACHINE_STATE_SAVE(ID)
#endif
diff --git a/gcc/tm.texi b/gcc/tm.texi
index d3357c1..d648344 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -7815,4 +7815,12 @@ specifies where the linker should look for libraries.
You need only define this macro if the default of @samp{"LIBRARY_PATH"}
is wrong.
+
+@findex TARGET_HAS_F_SETLKW
+@item TARGET_HAS_F_SETLKW
+Define this macro iff the target supports file locking with fcntl / F_SETLKW.
+Note that this functionality is part of POSIX.
+Defining @code{TARGET_HAS_F_SETLKW} will enable the test coverage code
+to use file locking when exiting a program, which avoids race conditions
+if the program has forked.
@end table
diff --git a/gcc/tree.h b/gcc/tree.h
index d6e51a0..976f70f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2431,7 +2431,7 @@ extern struct rtx_def *emit_line_note_force PARAMS ((char *, int));
/* In calls.c */
extern void special_function_p PARAMS ((tree, int *, int *,
- int *, int *));
+ int *, int *, int *));
/* In c-typeck.c */
extern int mark_addressable PARAMS ((tree));