[rrd-developers] [PATCH 1/2] Add utility functions to allocate pointers in variable size chunks.

kevin brintnall kbrint at rufus.net
Mon Nov 9 16:19:33 CET 2009


On Mon, Nov 09, 2009 at 09:57:43AM +0100, Tobias Oetiker wrote:
> Hi Kevin,
> 
> since 1.4.x is now out, I would like to hold off on adding new
> public functions to the 1.4 branche ... these would go into the new
> trunk. or is there also a bug-fix component to this change ?

Tobi,

This improves performance for implementations where realloc() may be
expensive..  It causes the realloc() for cache_item_t.values to be in
larger chunks, and less frequent.

This is in response to Thorsten's performance testing, where he sees CPU
spikes at specific times after start-up, when his cache_item_t.values
arrays all simultaneously cross some size threshold.

Up to you.

-- 
 kevin brintnall =~ /kbrint at rufus.net/


> cheers
> tobi
> 
> Oct 31 kevin brintnall wrote:
> 
> > ---
> >  doc/librrd.pod  |   18 ++++++++++++++++++
> >  src/rrd.h       |    4 ++++
> >  src/rrd_utils.c |   53 ++++++++++++++++++++++++++++++++++++++++++-----------
> >  3 files changed, 64 insertions(+), 11 deletions(-)
> >
> > diff --git a/doc/librrd.pod b/doc/librrd.pod
> > index 038746c..396e50c 100644
> > --- a/doc/librrd.pod
> > +++ b/doc/librrd.pod
> > @@ -81,6 +81,16 @@ end of the new C<dest>.  Returns 1 on success, 0 on failure.
> >      if (!rrd_add_ptr(&arr, &arr_size, elem))
> >          handle_failure();
> >
> > +=item B<rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src, size_t *alloc, size_t chunk)>
> > +
> > +Like C<rrd_add_ptr>, except the destination is allocated in chunks of
> > +C<chunk>.  C<alloc> points to the number of entries allocated, whereas
> > +C<dest_size> points to the number of valid pointers.  If more pointers are
> > +needed, C<chunk> pointers are allocated and C<alloc> is increased
> > +accordingly.  C<alloc> must be E<gt>= C<dest_size>.
> > +
> > +This method improves performance on hosts with expensive C<realloc()>.
> > +
> >  =item B<rrd_add_strdup(char ***dest, size_t *dest_size, char *src)>
> >
> >  Like C<rrd_add_ptr>, except adds a C<strdup> of the source string.
> > @@ -91,6 +101,14 @@ Like C<rrd_add_ptr>, except adds a C<strdup> of the source string.
> >      if (!rrd_add_strdup(&arr, &arr_size, str))
> >          handle_failure();
> >
> > +=item B<rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src, size_t *alloc, size_t chunk)>
> > +
> > +Like C<rrd_add_strdup>, except the destination is allocated in chunks of
> > +C<chunk>.  C<alloc> points to the number of entries allocated, whereas
> > +C<dest_size> points to the number of valid pointers.  If more pointers are
> > +needed, C<chunk> pointers are allocated and C<alloc> is increased
> > +accordingly.  C<alloc> must be E<gt>= C<dest_size>.
> > +
> >  =item B<rrd_free_ptrs(void ***src, size_t *cnt)>
> >
> >  Free an array of pointers allocated by C<rrd_add_ptr> or
> > diff --git a/src/rrd.h b/src/rrd.h
> > index ce7e749..6008794 100644
> > --- a/src/rrd.h
> > +++ b/src/rrd.h
> > @@ -333,8 +333,12 @@ int       rrd_proc_start_end(
> >
> >      long rrd_random(void);
> >
> > +    int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
> > +                          size_t *alloc, size_t chunk);
> >      int rrd_add_ptr(void ***dest, size_t *dest_size, void *src);
> >      int rrd_add_strdup(char ***dest, size_t *dest_size, char *src);
> > +    int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
> > +                             size_t *alloc, size_t chunk);
> >      void rrd_free_ptrs(void ***src, size_t *cnt);
> >
> >      int rrd_mkdir_p(const char *pathname, mode_t mode);
> > diff --git a/src/rrd_utils.c b/src/rrd_utils.c
> > index 3936cff..6853c66 100644
> > --- a/src/rrd_utils.c
> > +++ b/src/rrd_utils.c
> > @@ -50,29 +50,53 @@ long rrd_random(void)
> >      return random();
> >  }
> >
> > -/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
> > - * realloc as necessary.  returns 1 on success, 0 on failure.
> > +/* rrd_add_ptr_chunk: add a pointer to a dynamically sized array of
> > + * pointers, realloc as necessary in multiples of "chunk".
> > + *
> > + * "alloc" is the number of pointers allocated
> > + * "dest_size" is the number of valid pointers
> > + *
> > + * returns 1 on success, 0 on failure.
> >   */
> >
> > -int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
> > +int rrd_add_ptr_chunk(void ***dest, size_t *dest_size, void *src,
> > +                      size_t *alloc, size_t chunk)
> >  {
> >      void **temp;
> >
> >      assert(dest != NULL);
> > +    assert(alloc != NULL);
> > +    assert(*alloc >= *dest_size);
> >
> > -    temp = (void **) rrd_realloc(*dest, (*dest_size+1) * sizeof(*dest));
> > -    if (!temp)
> > -        return 0;
> > +    if (*alloc == *dest_size)
> > +    {
> > +        temp = (void **) rrd_realloc(*dest, (*alloc+chunk) * sizeof(*dest));
> > +        if (!temp)
> > +            return 0;
> >
> > -    *dest = temp;
> > -    temp[*dest_size] = src;
> > +        *dest = temp;
> > +        *alloc += chunk;
> > +    }
> > +
> > +    (*dest)[*dest_size] = src;
> >      (*dest_size)++;
> >
> >      return 1;
> >  }
> >
> > -/* like rrd_add_ptr, but calls strdup() on a string first. */
> > -int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
> > +/* rrd_add_ptr: add a pointer to a dynamically sized array of pointers,
> > + * realloc as necessary.  returns 1 on success, 0 on failure.
> > + */
> > +int rrd_add_ptr(void ***dest, size_t *dest_size, void *src)
> > +{
> > +    size_t alloc = *dest_size;
> > +
> > +    return rrd_add_ptr_chunk(dest, dest_size, src, &alloc, 1);
> > +}
> > +
> > +/* like rrd_add_ptr_chunk, but calls strdup() on a string first. */
> > +int rrd_add_strdup_chunk(char ***dest, size_t *dest_size, char *src,
> > +                         size_t *alloc, size_t chunk)
> >  {
> >      char *dup_src;
> >      int add_ok;
> > @@ -84,13 +108,20 @@ int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
> >      if (!dup_src)
> >          return 0;
> >
> > -    add_ok = rrd_add_ptr((void ***)dest, dest_size, (void *)dup_src);
> > +    add_ok = rrd_add_ptr_chunk((void ***)dest, dest_size, (void *)dup_src, alloc, chunk);
> >      if (!add_ok)
> >          free(dup_src);
> >
> >      return add_ok;
> >  }
> >
> > +int rrd_add_strdup(char ***dest, size_t *dest_size, char *src)
> > +{
> > +    size_t alloc = *dest_size;
> > +
> > +    return rrd_add_strdup_chunk(dest, dest_size, src, &alloc, 1);
> > +}
> > +
> >  void rrd_free_ptrs(void ***src, size_t *cnt)
> >  {
> >      void **sp;
> >
> 
> -- 
> Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland
> http://it.oetiker.ch tobi at oetiker.ch ++41 62 775 9902 / sb: -9900



More information about the rrd-developers mailing list