From: Sebastien GODARD Date: Sun, 4 Mar 2018 09:53:55 +0000 (+0100) Subject: sar: Better assess size of buffers that need to be reallocated X-Git-Tag: v11.7.3~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=16359471b3926bc2eb5375162b610069afc1f31d;p=sysstat sar: Better assess size of buffers that need to be reallocated 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 --- diff --git a/pr_stats.c b/pr_stats.c index 90073b2..9ba63a5 100644 --- a/pr_stats.c +++ b/pr_stats.c @@ -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 871c578..0d75b60 100644 --- 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 diff --git a/sa_common.c b/sa_common.c index a5579a8..75c90ba 100644 --- a/sa_common.c +++ b/sa_common.c @@ -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 8ba575a..c0c85ab 100644 --- 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]); }