]> granicus.if.org Git - sysstat/commitdiff
sar: Better assess size of buffers that need to be reallocated
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 4 Mar 2018 09:53:55 +0000 (10:53 +0100)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 4 Mar 2018 09:53:55 +0000 (10:53 +0100)
When a buffer needs to be reallocated, doubling its size may not be
enough to contain all the additional items.
Assess the needed size based on a value giving the minimum number of
items the buffer should be able to contain.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
pr_stats.c
sa.h
sa_common.c
sar.c

index 90073b2734a4f13f21f7058684ce8981c564d372..9ba63a512da5e5030171f40f4e93572094a9e4f9 100644 (file)
@@ -2673,7 +2673,7 @@ void stub_print_pwr_usb_stats(struct activity *a, int curr, int dispavg)
                                 * No free slot has been found for current device.
                                 * So enlarge buffers then save device in list.
                                 */
-                               reallocate_all_buffers(a);
+                               reallocate_all_buffers(a, j);
                                sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize);
                                *sum = *suc;
                                a->nr[2] = j + 1;
@@ -2821,7 +2821,7 @@ __print_funct_t stub_print_filesystem_stats(struct activity *a, int prev, int cu
                                 * No free slot has been found for current filesystem.
                                 * So enlarge buffers then save filesystem in list.
                                 */
-                               reallocate_all_buffers(a);
+                               reallocate_all_buffers(a, j);
                                sfm = (struct stats_filesystem *) ((char *) a->buf[2] + j * a->msize);
                                *sfm = *sfc;
                                a->nr[2] = j + 1;
diff --git a/sa.h b/sa.h
index 871c57814b56f2b5544d4525fa5a3b4ddcc2c147..0d75b60726796a1fb72f7a51bfc2be03a2d836f6 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -1289,7 +1289,7 @@ __nr_t read_nr_value
 int read_record_hdr
        (int, void *, struct record_header *, struct file_header *, int, int);
 void reallocate_all_buffers
-       (struct activity *);
+       (struct activity *, __nr_t);
 void remap_struct
        (unsigned int [], unsigned int [], void *, unsigned int);
 void replace_nonprintable_char
index a5579a8b9dc62ecd296d1148bd135f0100b2cda4..75c90ba4c19768544f2967a9481682a52b88c787 100644 (file)
@@ -435,23 +435,31 @@ void free_structures(struct activity *act[])
 
 /*
  ***************************************************************************
- * Reallocate all the buffers for given activity. The new size is the double
- * of the original one.
+ * Reallocate all the buffers for a given activity.
  *
  * IN:
- * @a  Activity whose buffers need to be reallocated.
+ * @a          Activity whose buffers need to be reallocated.
+ * @nr_min     Minimum number of items that the new buffers should be able
+ *             to receive.
  ***************************************************************************
  */
-void reallocate_all_buffers(struct activity *a)
+void reallocate_all_buffers(struct activity *a, __nr_t nr_min)
 {
        int j;
        size_t nr_realloc;
 
+       if (nr_min <= 0) {
+               nr_min = 1;
+       }
        if (!a->nr_allocated) {
-               nr_realloc = (a->nr_ini ? a->nr_ini : 1);
+               nr_realloc = nr_min;
        }
        else {
-               nr_realloc = a->nr_allocated * 2;
+               nr_realloc = a->nr_allocated;
+               do {
+                       nr_realloc = nr_realloc * 2;
+               }
+               while (nr_realloc < nr_min);
        }
 
        for (j = 0; j < 3; j++) {
@@ -460,7 +468,7 @@ void reallocate_all_buffers(struct activity *a)
                /* Init additional space which has been allocated */
                if (a->nr_allocated) {
                        memset(a->buf[j] + a->msize * a->nr_allocated * a->nr2, 0,
-                              (size_t) a->msize * (size_t) a->nr_allocated * (size_t) a->nr2);
+                              (size_t) a->msize * (size_t) (nr_realloc - a->nr_allocated) * (size_t) a->nr2);
                }
        }
 
@@ -1514,7 +1522,7 @@ void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr,
 
                /* Reallocate buffers if needed */
                if (nr_value > act[p]->nr_allocated) {
-                       reallocate_all_buffers(act[p]);
+                       reallocate_all_buffers(act[p], nr_value);
                }
 
                /*
@@ -2649,7 +2657,7 @@ int print_special_record(struct record_header *record_hdr, unsigned int l_flags,
                p = get_activity_position(act, A_CPU, EXIT_IF_NOT_FOUND);
                act[p]->nr_ini = file_hdr->sa_cpu_nr;
                if (act[p]->nr_ini > act[p]->nr_allocated) {
-                       reallocate_all_buffers(act[p]);
+                       reallocate_all_buffers(act[p], act[p]->nr_ini);
                }
 
                if (!dp)
diff --git a/sar.c b/sar.c
index 8ba575a7f345aaaa610b88a7c7236f13ffd1d049..c0c85ab0a4b6a0d48331f39150360e5ffa2a16b7 100644 (file)
--- a/sar.c
+++ b/sar.c
@@ -685,7 +685,7 @@ void read_sadc_stat_bunch(int curr)
                                print_read_error(INCONSISTENT_INPUT_DATA);
                        }
                        if (act[p]->nr[curr] > act[p]->nr_allocated) {
-                               reallocate_all_buffers(act[p]);
+                               reallocate_all_buffers(act[p], act[p]->nr[curr]);
                        }