This is an automated email from Gerrit.

"Richard Allen <rsa...@gmail.com>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/8739

-- gerrit

commit 7dd7db6b6d31173a5fcd6125711f34e45d8d97d6
Author: Richard Allen <rsa...@gmail.com>
Date:   Mon Feb 3 21:21:15 2025 -0600

    target: multiple profiling histograms
    
    Encode profiling data in multiple histograms.
    This provides much smaller encoding for target
    systems with sparse address maps.
    
    Change-Id: I38276dd1be011ce5781b0264b7cbb09a3aa1a2b5
    Signed-off-by: Richard Allen <rsa...@gmail.com>

diff --git a/src/target/target.c b/src/target/target.c
index f47d061903..9db32f8b63 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -4210,13 +4210,13 @@ typedef unsigned char UNIT[2];  /* unit of profiling */
 static void write_gmon(const uint32_t *samples, uint32_t sample_num, const 
char *filename,
                        struct target *target, uint32_t duration_ms)
 {
-       uint32_t i;
-
        if (!sample_num) {
                LOG_WARNING("no samples to write");
                return;
        }
 
+       float sample_rate = sample_num / (duration_ms / 1000.0);
+
        FILE *f = fopen(filename, "wb");
        if (!f)
                return;
@@ -4226,47 +4226,49 @@ static void write_gmon(const uint32_t *samples, 
uint32_t sample_num, const char
        write_long(f, 0, target); /* padding */
        write_long(f, 0, target); /* padding */
 
-       uint8_t zero = 0;  /* GMON_TAG_TIME_HIST */
-       write_data(f, &zero, 1);
-
-       /* figure out bucket size */
-       uint32_t min = samples[0];
-       /* max should be (largest sample + 1)
-        * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
-       uint32_t max = samples[sample_num-1] + 1;
-       uint32_t address_space = max - min;
-
-       /* FIXME: What is the reasonable number of buckets?
-        * The profiling result will be more accurate if there are enough 
buckets. */
-       static const uint32_t max_buckets = 128 * 1024; /* maximum buckets. */
-       uint32_t num_buckets = address_space / sizeof(UNIT);
-       if (num_buckets > max_buckets)
-               num_buckets = max_buckets;
-
-       /* append binary memory gmon.out &profile_hist_hdr 
((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
-       write_long(f, min, target);                     /* low_pc */
-       write_long(f, max, target);                     /* high_pc */
-       write_long(f, num_buckets, target);     /* # of buckets */
-       float sample_rate = sample_num / (duration_ms / 1000.0);
-       write_long(f, sample_rate, target);
-       write_string(f, "seconds");
-       for (i = 0; i < (15-strlen("seconds")); i++)
+       while (sample_num) {
+               /* figure out bucket size */
+               uint32_t min = samples[0];
+               uint32_t max = samples[0];
+               uint32_t this_pass = 1;
+               while (this_pass < sample_num && samples[this_pass] - max < 32) 
{
+                       max = samples[this_pass++];
+               }
+
+               /* max should be (largest sample + 1)
+                * Refer to binutils/gprof/hist.c (find_histogram_for_pc) */
+               max++;
+               uint32_t address_space = max - min;
+
+               uint8_t zero = 0;  /* GMON_TAG_TIME_HIST */
                write_data(f, &zero, 1);
-       write_string(f, "s");
-
-       /*append binary memory gmon.out profile_hist_data (profile_hist_data + 
profile_hist_hdr.hist_size) */
-       uint32_t bidx;
-       for (i = 0, bidx = 0; bidx < num_buckets; ++bidx) {
-               int val = 0;
-               long long bmax = min + (long long)address_space * (bidx + 1) / 
num_buckets;
-               for ( ; i < sample_num && samples[i] < bmax; ++i)
-                       if (val < 65535)
-                               val++;
-
-               uint8_t data[2];
-               data[0] = val & 0xff;
-               data[1] = (val >> 8) & 0xff;
-               write_data(f, data, 2);
+
+               /* append binary memory gmon.out &profile_hist_hdr 
((char*)&profile_hist_hdr + sizeof(struct gmon_hist_hdr)) */
+               write_long(f, min, target);                     /* low_pc */
+               write_long(f, max, target);                     /* high_pc */
+               write_long(f, address_space, target);   /* # of buckets */
+               write_long(f, sample_rate, target);
+               write_string(f, "seconds");
+               for (uint32_t i = 0; i < (15-strlen("seconds")); i++)
+                       write_data(f, &zero, 1);
+               write_string(f, "s");
+
+               /*append binary memory gmon.out profile_hist_data 
(profile_hist_data + profile_hist_hdr.hist_size) */
+               for (uint32_t i = 0, bidx = 0; bidx < address_space; ++bidx) {
+                       int val = 0;
+                       long long bmax = min + bidx;
+                       for ( ; i < this_pass && samples[i] <= bmax; ++i)
+                               if (val < 65535)
+                                       val++;
+
+                       uint8_t data[2];
+                       data[0] = val & 0xff;
+                       data[1] = (val >> 8) & 0xff;
+                       write_data(f, data, 2);
+               }
+
+               samples += this_pass;
+               sample_num -= this_pass;
        }
 
        fclose(f);

-- 

Reply via email to