aboutsummaryrefslogtreecommitdiff
path: root/libgcc/libgcov-interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc/libgcov-interface.c')
-rw-r--r--libgcc/libgcov-interface.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c
index d4a7f50..f73666c 100644
--- a/libgcc/libgcov-interface.c
+++ b/libgcc/libgcov-interface.c
@@ -42,8 +42,7 @@ void __gcov_dump (void) {}
#else
-extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
-extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
+extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
#ifdef L_gcov_flush
@@ -77,8 +76,8 @@ __gcov_flush (void)
init_mx_once ();
__gthread_mutex_lock (&__gcov_flush_mx);
- gcov_exit ();
- gcov_clear ();
+ __gcov_dump_one (&__gcov_root);
+ __gcov_reset ();
__gthread_mutex_unlock (&__gcov_flush_mx);
}
@@ -87,31 +86,61 @@ __gcov_flush (void)
#ifdef L_gcov_reset
+/* Reset all counters to zero. */
+
+static void
+gcov_clear (const struct gcov_info *list)
+{
+ const struct gcov_info *gi_ptr;
+
+ for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
+ {
+ unsigned f_ix;
+
+ for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
+ {
+ unsigned t_ix;
+ const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
+
+ if (!gfi_ptr || gfi_ptr->key != gi_ptr)
+ continue;
+ const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
+ for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
+ {
+ if (!gi_ptr->merge[t_ix])
+ continue;
+
+ memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
+ ci_ptr++;
+ }
+ }
+ }
+}
+
/* Function that can be called from application to reset counters to zero,
in order to collect profile in region of interest. */
void
__gcov_reset (void)
{
- gcov_clear ();
+ gcov_clear (__gcov_root.list);
+ __gcov_root.dumped = 0;
}
#endif /* L_gcov_reset */
#ifdef L_gcov_dump
-
/* Function that can be called from application to write profile collected
so far, in order to collect profile in region of interest. */
void
__gcov_dump (void)
{
- gcov_exit ();
+ __gcov_dump_one (&__gcov_root);
}
#endif /* L_gcov_dump */
-
#ifdef L_gcov_fork
/* A wrapper for the fork function. Flushes the accumulated profiling data, so
that they are not counted twice. */
@@ -120,7 +149,6 @@ pid_t
__gcov_fork (void)
{
pid_t pid;
- extern __gthread_mutex_t __gcov_flush_mx;
__gcov_flush ();
pid = fork ();
if (pid == 0)