changeset 2451:8a8997415857

* include/profile.h: Declare profile_off. * src/profile.c: Added support for invoking profile_on() multiple times. It now stops profiling and sets up a fresh profiling range on every invocation using new profile_off() function. * doc/profile.sgml: Document it.
author jlarmour
date Fri, 21 Dec 2007 16:47:15 +0000
parents 0f68ebea87e6
children 5298598f7174
files packages/services/profile/gprof/current/ChangeLog packages/services/profile/gprof/current/doc/profile.sgml packages/services/profile/gprof/current/include/profile.h packages/services/profile/gprof/current/src/profile.c
diffstat 4 files changed, 65 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/packages/services/profile/gprof/current/ChangeLog
+++ b/packages/services/profile/gprof/current/ChangeLog
@@ -1,3 +1,12 @@
+2007-12-14  Oyvind Harboe  <oyvind.harboe@zylin.com>
+2007-12-21  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* include/profile.h: Declare profile_off.
+	* src/profile.c: Added support for invoking profile_on() multiple
+	times. It now stops profiling and sets up a fresh profiling range
+	on every invocation using new profile_off() function.
+	* doc/profile.sgml: Document it.
+	
 2005-05-13  Peter Korsgaard  <jacmet@sunsite.dk>
 
 	* doc/profile.sgml: Fixed typo in HAL support section.
--- a/packages/services/profile/gprof/current/doc/profile.sgml
+++ b/packages/services/profile/gprof/current/doc/profile.sgml
@@ -267,6 +267,19 @@ clock.
       </varlistentry>
     </variablelist>
     <para>
+<function>profile_on</function> can be invoked multiple times, and
+on subsequent invocations, it will delete profiling data
+and allocate a fresh profiling range.
+    </para>
+    <para>
+Profiling can be turned off using the function
+<function>profile_off</function>:
+<programlisting>
+void profile_off(void);
+</programlisting>
+This will also reset any existing profile data.
+    </para>
+    <para>
 If the eCos configuration includes a TCP/IP stack and if a tftp daemon
 will be used to <link linkend="gprof-extract">extract</link> the data
 from the target then the call to <function>profile_on</function>
--- a/packages/services/profile/gprof/current/include/profile.h
+++ b/packages/services/profile/gprof/current/include/profile.h
@@ -65,6 +65,9 @@
 __externC void profile_on(void *start_addr, void *end_addr, 
                           int bucket_size, int sample_resolution);
 
+// Disable and reset profiling
+__externC void profile_off(void);
+
 // Callback used by timer routine
 __externC void __profile_hit(CYG_ADDRWORD pc);
 
--- a/packages/services/profile/gprof/current/src/profile.c
+++ b/packages/services/profile/gprof/current/src/profile.c
@@ -435,6 +435,32 @@ static struct tftpd_fileops profile_tftp
 #endif
 
 // ----------------------------------------------------------------------------
+// stop profiling
+void 
+profile_off(void)
+{
+    // suspend currently running profiling
+    profile_enabled = 0;
+    // Clear all pre-existing profile data
+    profile_reset();
+    if (profile_hist_data) {
+    	free(profile_hist_data);
+        profile_hist_data = NULL;
+    }
+#ifdef CYGPKG_PROFILE_CALLGRAPH
+    if (profile_arc_hashtable) {
+    	free(profile_arc_hashtable);
+        profile_arc_hashtable=NULL;
+    }
+    if (profile_arc_records) {
+    	free(profile_arc_records);
+        profile_arc_records=NULL;
+    }
+#endif
+}
+
+
+// ----------------------------------------------------------------------------
 // profile_on() has to be called by application code to start profiling.
 // Application code will determine the start and end addresses, usually
 // _stext and _etext, but it is possible to limit profiling to only
@@ -443,6 +469,12 @@ static struct tftpd_fileops profile_tftp
 // but requires more memory. The resolution is used to initialize the
 // profiling timer: more frequent interrupts means more accurate results
 // but increases the risk of an overflow.
+//
+// profile_on() can be invoked multiple times. If invoked a second time
+// it will stop the current profiling run and create a new profiling 
+// range.
+
+
 
 void 
 profile_on(void *_start, void *_end, int _bucket_size, int resolution)
@@ -451,6 +483,13 @@ profile_on(void *_start, void *_end, int
     cyg_uint32      version     = GMON_VERSION;
     CYG_ADDRWORD    text_size   = (CYG_ADDRWORD)_end - (CYG_ADDRWORD)_start;
 
+    if (profile_enabled)
+    {
+    	// invoking profile_on a second time
+    	profile_off();
+    }
+    
+    
     // Initialize statics. This also ensures that they won't be
     // garbage collected by the linker so a gdb script can safely
     // reference them.
@@ -540,6 +579,7 @@ profile_on(void *_start, void *_end, int
 
 #ifdef CYGPKG_PROFILE_TFTP    
     // Create a TFTP server to provide the data
+    // invoking this a second time is harmless
     (void) tftpd_start(CYGNUM_PROFILE_TFTP_PORT, &profile_tftp_fileops);
 #endif    
 }