[Mesa-dev] [PATCH 1/7] ralloc: add a new printing helper ralloc_sprint_rewrite_tail

Kenneth Graunke kenneth at whitecape.org
Sun Jan 1 03:26:24 UTC 2017


On Sunday, January 1, 2017 1:34:26 AM PST Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
> 
> This one is much faster when you don't need vsprintf.
> ---
>  src/util/ralloc.c | 25 +++++++++++++++++++++++++
>  src/util/ralloc.h | 24 ++++++++++++++++++++++++
>  2 files changed, 49 insertions(+)
> 
> diff --git a/src/util/ralloc.c b/src/util/ralloc.c
> index 980e4e4..7976ca6 100644
> --- a/src/util/ralloc.c
> +++ b/src/util/ralloc.c
> @@ -522,20 +522,45 @@ ralloc_vasprintf_rewrite_tail(char **str, size_t *start, const char *fmt,
>     ptr = resize(*str, *start + new_length + 1);
>     if (unlikely(ptr == NULL))
>        return false;
>  
>     vsnprintf(ptr + *start, new_length + 1, fmt, args);
>     *str = ptr;
>     *start += new_length;
>     return true;
>  }
>  
> +bool
> +ralloc_sprint_rewrite_tail(char **str, size_t *start, const char *text,
> +                           unsigned text_length)
> +{

Cool.  I always thought about adding this.

Can we shorten it to "ralloc_rewrite_tail()" or
"ralloc_str_rewrite_tail()"?

> +   char *ptr;
> +
> +   assert(str != NULL);
> +
> +   if (unlikely(*str == NULL)) {
> +      /* Assuming a NULL context is probably bad, but it's expected behavior. */
> +      *str = ralloc_strdup(NULL, text);
> +      *start = strlen(*str);
> +      return true;
> +   }
> +
> +   ptr = resize(*str, *start + text_length + 1);
> +   if (unlikely(ptr == NULL))
> +      return false;
> +
> +   memcpy(ptr + *start, text, text_length + 1); /* also copy '\0' */

I don't know how I feel about copying the \0 from the source string.
I suppose that works, and is probably more efficient.  But I noticed
that this has an awful lot of similarity to the cat() helper (for
ralloc_strncat), which copies n bytes and appends an \0 explicitly.

I suppose if we wanted to add a ralloc_strn_rewrite_tail(), we'd need
to do it that way.  I don't know that there's any use in that, though.

> +   *str = ptr;
> +   *start += text_length;
> +   return true;
> +}
> +
>  /***************************************************************************
>   * Linear allocator for short-lived allocations.
>   ***************************************************************************
>   *
>   * The allocator consists of a parent node (2K buffer), which requires
>   * a ralloc parent, and child nodes (allocations). Child nodes can't be freed
>   * directly, because the parent doesn't track them. You have to release
>   * the parent node in order to release all its children.
>   *
>   * The allocator uses a fixed-sized buffer with a monotonically increasing
> diff --git a/src/util/ralloc.h b/src/util/ralloc.h
> index 3e2d342..6c31a6d 100644
> --- a/src/util/ralloc.h
> +++ b/src/util/ralloc.h
> @@ -401,20 +401,44 @@ bool ralloc_asprintf_append (char **str, const char *fmt, ...)
>   * \sa ralloc_strcat
>   *
>   * \p str will be updated to the new pointer unless allocation fails.
>   *
>   * \return True unless allocation failed.
>   */
>  bool ralloc_vasprintf_append(char **str, const char *fmt, va_list args);
>  /// @}
>  
>  /**
> + * Rewrite the tail of an existing string, starting at a given index.
> + *
> + * Overwrites the contents of *str starting at \p start with "text",
> + * including a new null-terminator.  Allocates more memory as necessary.
> + *
> + * This can be used to append formatted text when the length of the existing
> + * string is already known, saving a strlen() call.
> + *
> + * \sa ralloc_asprintf_rewrite_tail
> + *
> + * \param str          The string to be updated.
> + * \param start        The index to start appending new data at.
> + * \param text         The input string terminated by zero.
> + * \param text_length  The length of the input string.
> + *
> + * \p str will be updated to the new pointer unless allocation fails.
> + * \p start will be increased by the length of the newly formatted text.
> + *
> + * \return True unless allocation failed.
> + */
> +bool ralloc_sprint_rewrite_tail(char **str, size_t *start, const char *text,
> +                                unsigned text_length);
> +
> +/**
>   * Declare C++ new and delete operators which use ralloc.
>   *
>   * Placing this macro in the body of a class makes it possible to do:
>   *
>   * TYPE *var = new(mem_ctx) TYPE(...);
>   * delete var;
>   *
>   * which is more idiomatic in C++ than calling ralloc.
>   */
>  #define DECLARE_ALLOC_CXX_OPERATORS_TEMPLATE(TYPE, ALLOC_FUNC)           \
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20161231/7187a645/attachment.sig>


More information about the mesa-dev mailing list