[PATCH] stdlib: Reinstate stable mergesort implementation on qsort

Florian Weimer fweimer@redhat.com
Fri Dec 8 17:36:30 GMT 2023


* Adhemerval Zanella:

> +static void
> +indirect_msort_with_tmp (const struct msort_param *p, void *b, size_t n,
> +			 size_t s)
> +{
> +  /* Indirect sorting.  */
> +  char *ip = (char *) b;
> +  void **tp = (void **) (p->t + n * sizeof (void *));
> +  void **t = tp;
> +  void *tmp_storage = (void *) (tp + n);


> +	memcpy (tmp_storage, ip, s);


>  __qsort_r (void *const pbase, size_t total_elems, size_t size,
>  	   __compar_d_fn_t cmp, void *arg)
>  {
>    if (total_elems <= 1)
>      return;
>  
> +  char tmp[QSORT_STACK_SIZE];
> +  size_t total_size = total_elems * size;
> +  char *buf;

I don't see how the total_size computation makes sure that
the tmp_storage place actually exists when …

> +  if (total_size < sizeof buf)
> +    buf = tmp;
> +  else
> +    {
> +      int save = errno;
> +      buf = malloc (total_size);
> +      __set_errno (save);
> +      if (buf == NULL)
> +	{
> +	  /* Fallback to heapsort in case of memory failure.  */
> +	  heapsort_r (pbase, total_elems - 1, size, cmp, arg);
> +	  return;
> +	}
> +    }
>  
> +  if (size > INDIRECT_SORT_SIZE_THRES)
>      {
> +      const struct msort_param msort_param =
> +	{
> +	  .s = sizeof (void *),
> +	  .cmp = cmp,
> +	  .arg = arg,
> +	  .var = SWAP_VOID_ARG,
> +	  .t = buf,
> +	};
> +      indirect_msort_with_tmp (&msort_param, pbase, total_elems, size);

it is passed to indirect_msort_with_tmp here.

Thanks,
Florian



More information about the Libc-alpha mailing list