> +Honza and Nathan. > > David > > On Thu, May 3, 2012 at 10:52 AM, Teresa Johnson <tejohn...@google.com> wrote: > > This patch adds functionality to libgcov to enable user applications to > > collect profile data only in regions of interest. This is useful, for > > example, to collect profile data from a long-running server only > > during the time when it is serving requests. > > > > Specifically, the new routines __gcov_reset will clear all profile counters > > to zero and __gcov_dump will write out the profile information collected so > > far. A global variable is used to prevent writing out the profile a > > second time during exit. > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. Is this ok for trunk?
This seems resonable things to do. You need to add an documentation and make sure they go new L_* section, since not every app using libgcov needs necesarily those two. Honza > > > > Thanks, > > Teresa > > > > 2012-05-03 Teresa Johnson <tejohn...@google.com> > > > > * libgcc/libgcov.c (gcov_clear, __gcov_reset): New functions. > > (__gcov_dump): Ditto. > > (gcov_dump_complete): New global variable. > > (__gcov_flush): Outline functionality now in gcov_clear. > > * gcc/gcov-io.h (__gcov_reset, __gcov_dump): Declare. > > > > Index: libgcc/libgcov.c > > =================================================================== > > --- libgcc/libgcov.c (revision 187048) > > +++ libgcc/libgcov.c (working copy) > > @@ -48,6 +48,8 @@ see the files COPYING3 and COPYING.RUNTIME respect > > #ifdef L_gcov > > void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {} > > void __gcov_flush (void) {} > > +void __gcov_reset (void) {} > > +void __gcov_dump (void) {} > > #endif > > > > #ifdef L_gcov_merge_add > > @@ -91,6 +93,9 @@ static struct gcov_info *gcov_list; > > /* Size of the longest file name. */ > > static size_t gcov_max_filename = 0; > > > > +/* Flag when the profile has already been dumped via __gcov_dump(). */ > > +static int gcov_dump_complete = 0; > > + > > /* Make sure path component of the given FILENAME exists, create > > missing directories. FILENAME must be writable. > > Returns zero on success, or -1 if an error occurred. */ > > @@ -286,6 +291,11 @@ gcov_exit (void) > > char *gi_filename, *gi_filename_up; > > gcov_unsigned_t crc32 = 0; > > > > + /* Prevent the counters from being dumped a second time on exit when the > > + application already wrote out the profile using __gcov_dump(). */ > > + if (gcov_dump_complete) > > + return; > > + > > memset (&all_prg, 0, sizeof (all_prg)); > > /* Find the totals for this execution. */ > > memset (&this_prg, 0, sizeof (this_prg)); > > @@ -679,6 +689,37 @@ gcov_exit (void) > > } > > } > > > > +/* Reset all counters to zero. */ > > + > > +static void > > +gcov_clear (void) > > +{ > > + const struct gcov_info *gi_ptr; > > + > > + for (gi_ptr = gcov_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++; > > + } > > + } > > + } > > +} > > + > > /* Add a new object file onto the bb chain. Invoked automatically > > when running an object file's global ctors. */ > > > > @@ -730,38 +771,38 @@ init_mx_once (void) > > void > > __gcov_flush (void) > > { > > - const struct gcov_info *gi_ptr; > > - > > init_mx_once (); > > __gthread_mutex_lock (&__gcov_flush_mx); > > > > gcov_exit (); > > - for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next) > > - { > > - unsigned f_ix; > > + gcov_clear (); > > > > - 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]; > > + __gthread_mutex_unlock (&__gcov_flush_mx); > > +} > > > > - 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. */ > > > > - __gthread_mutex_unlock (&__gcov_flush_mx); > > +void > > +__gcov_reset (void) > > +{ > > + gcov_clear (); > > + /* Re-enable dumping to support collecting profile in multiple regions > > + of interest. */ > > + gcov_dump_complete = 0; > > } > > > > +/* 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 (); > > + /* Prevent profile from being dumped a second time on application exit. > > */ > > + gcov_dump_complete = 1; > > +} > > + > > #endif /* L_gcov */ > > > > #ifdef L_gcov_merge_add > > Index: gcc/gcov-io.h > > =================================================================== > > --- gcc/gcov-io.h (revision 187048) > > +++ gcc/gcov-io.h (working copy) > > @@ -458,6 +458,12 @@ extern void __gcov_init (struct gcov_info *) ATTRI > > /* Called before fork, to avoid double counting. */ > > extern void __gcov_flush (void) ATTRIBUTE_HIDDEN; > > > > +/* Function to reset all counters to 0. */ > > +extern void __gcov_reset (void); > > + > > +/* Function to enable early write of profile information so far. */ > > +extern void __gcov_dump (void); > > + > > /* The merge function that just sums the counters. */ > > extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN; > > > > > > -- > > This patch is available for review at http://codereview.appspot.com/6186044