Auto-sync with upstream branch master
Upstream commit: d1dcb565a1fb5829f9476a1438c30eccc4027d04 - Drop glibc-rh2248502-*.patch, workaround applied upstream - Fix type typo in “String/Array Conventions” doc - stdlib: Avoid element self-comparisons in qsort (#2248502) - elf: Add glibc.mem.decorate_maps tunable - linux: Decorate __libc_fatal error buffer - assert: Decorate error message buffer - malloc: Decorate malloc maps - nptl: Decorate thread stack on pthread_create - support: Add support_set_vma_name - linux: Add PR_SET_VMA_ANON_NAME support
This commit is contained in:
parent
4e9eab04ed
commit
ce2b6b8073
@ -1,447 +0,0 @@
|
|||||||
Revert "stdlib: Remove use of mergesort on qsort (BZ 21719)"
|
|
||||||
|
|
||||||
This reverts commit 03bf8357e8291857a435afcc3048e0b697b6cc04.
|
|
||||||
|
|
||||||
diff --git a/include/stdlib.h b/include/stdlib.h
|
|
||||||
index 580da9be15adf0c1..0ed8271d9bd76896 100644
|
|
||||||
--- a/include/stdlib.h
|
|
||||||
+++ b/include/stdlib.h
|
|
||||||
@@ -149,6 +149,8 @@ extern int __posix_openpt (int __oflag) attribute_hidden;
|
|
||||||
extern int __add_to_environ (const char *name, const char *value,
|
|
||||||
const char *combines, int replace)
|
|
||||||
attribute_hidden;
|
|
||||||
+extern void _quicksort (void *const pbase, size_t total_elems,
|
|
||||||
+ size_t size, __compar_d_fn_t cmp, void *arg);
|
|
||||||
|
|
||||||
extern int __on_exit (void (*__func) (int __status, void *__arg), void *__arg);
|
|
||||||
|
|
||||||
diff --git a/manual/argp.texi b/manual/argp.texi
|
|
||||||
index b77ad68285ecb732..0023441812d4e584 100644
|
|
||||||
--- a/manual/argp.texi
|
|
||||||
+++ b/manual/argp.texi
|
|
||||||
@@ -735,7 +735,7 @@ for options, bad phase of the moon, etc.
|
|
||||||
@c hol_set_group ok
|
|
||||||
@c hol_find_entry ok
|
|
||||||
@c hol_sort @mtslocale @acucorrupt
|
|
||||||
-@c qsort dup
|
|
||||||
+@c qsort dup @acucorrupt
|
|
||||||
@c hol_entry_qcmp @mtslocale
|
|
||||||
@c hol_entry_cmp @mtslocale
|
|
||||||
@c group_cmp ok
|
|
||||||
diff --git a/manual/locale.texi b/manual/locale.texi
|
|
||||||
index f6afa5dc44a2a016..720e0ca952a665bd 100644
|
|
||||||
--- a/manual/locale.texi
|
|
||||||
+++ b/manual/locale.texi
|
|
||||||
@@ -253,7 +253,7 @@ The symbols in this section are defined in the header file @file{locale.h}.
|
|
||||||
@c calculate_head_size ok
|
|
||||||
@c __munmap ok
|
|
||||||
@c compute_hashval ok
|
|
||||||
-@c qsort dup
|
|
||||||
+@c qsort dup @acucorrupt
|
|
||||||
@c rangecmp ok
|
|
||||||
@c malloc @ascuheap @acsmem
|
|
||||||
@c strdup @ascuheap @acsmem
|
|
||||||
@@ -275,6 +275,7 @@ The symbols in this section are defined in the header file @file{locale.h}.
|
|
||||||
@c realloc @ascuheap @acsmem
|
|
||||||
@c realloc @ascuheap @acsmem
|
|
||||||
@c fclose @ascuheap @asulock @acsmem @acsfd @aculock
|
|
||||||
+@c qsort @ascuheap @acsmem
|
|
||||||
@c alias_compare dup
|
|
||||||
@c libc_lock_unlock @aculock
|
|
||||||
@c _nl_explode_name @ascuheap @acsmem
|
|
||||||
diff --git a/manual/search.texi b/manual/search.texi
|
|
||||||
index a550858478f7fc83..5691bf2f2b2bb861 100644
|
|
||||||
--- a/manual/search.texi
|
|
||||||
+++ b/manual/search.texi
|
|
||||||
@@ -159,7 +159,7 @@ To sort an array using an arbitrary comparison function, use the
|
|
||||||
|
|
||||||
@deftypefun void qsort (void *@var{array}, size_t @var{count}, size_t @var{size}, comparison_fn_t @var{compare})
|
|
||||||
@standards{ISO, stdlib.h}
|
|
||||||
-@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
|
|
||||||
+@safety{@prelim{}@mtsafe{}@assafe{}@acunsafe{@acucorrupt{}}}
|
|
||||||
The @code{qsort} function sorts the array @var{array}. The array
|
|
||||||
contains @var{count} elements, each of which is of size @var{size}.
|
|
||||||
|
|
||||||
@@ -199,8 +199,9 @@ Functions}):
|
|
||||||
The @code{qsort} function derives its name from the fact that it was
|
|
||||||
originally implemented using the ``quick sort'' algorithm.
|
|
||||||
|
|
||||||
-The implementation of @code{qsort} in this library is an in-place sort
|
|
||||||
-and uses a constant extra space (allocated on the stack).
|
|
||||||
+The implementation of @code{qsort} in this library might not be an
|
|
||||||
+in-place sort and might thereby use an extra amount of memory to store
|
|
||||||
+the array.
|
|
||||||
@end deftypefun
|
|
||||||
|
|
||||||
@node Search/Sort Example
|
|
||||||
diff --git a/stdlib/Makefile b/stdlib/Makefile
|
|
||||||
index 6af606136e557910..b99bb34ae8f23730 100644
|
|
||||||
--- a/stdlib/Makefile
|
|
||||||
+++ b/stdlib/Makefile
|
|
||||||
@@ -96,6 +96,7 @@ routines := \
|
|
||||||
mbtowc \
|
|
||||||
mrand48 \
|
|
||||||
mrand48_r \
|
|
||||||
+ msort \
|
|
||||||
nrand48 \
|
|
||||||
nrand48_r \
|
|
||||||
old_atexit \
|
|
||||||
@@ -380,6 +381,7 @@ generated += \
|
|
||||||
# generated
|
|
||||||
|
|
||||||
CFLAGS-bsearch.c += $(uses-callbacks)
|
|
||||||
+CFLAGS-msort.c += $(uses-callbacks)
|
|
||||||
CFLAGS-qsort.c += $(uses-callbacks)
|
|
||||||
CFLAGS-system.c += -fexceptions
|
|
||||||
CFLAGS-system.os = -fomit-frame-pointer
|
|
||||||
diff --git a/stdlib/msort.c b/stdlib/msort.c
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000000000..bbaa5e9f82a75b78
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/stdlib/msort.c
|
|
||||||
@@ -0,0 +1,309 @@
|
|
||||||
+/* An alternative to qsort, with an identical interface.
|
|
||||||
+ This file is part of the GNU C Library.
|
|
||||||
+ Copyright (C) 1992-2023 Free Software Foundation, Inc.
|
|
||||||
+
|
|
||||||
+ The GNU C Library is free software; you can redistribute it and/or
|
|
||||||
+ modify it under the terms of the GNU Lesser General Public
|
|
||||||
+ License as published by the Free Software Foundation; either
|
|
||||||
+ version 2.1 of the License, or (at your option) any later version.
|
|
||||||
+
|
|
||||||
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
||||||
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
+ Lesser General Public License for more details.
|
|
||||||
+
|
|
||||||
+ You should have received a copy of the GNU Lesser General Public
|
|
||||||
+ License along with the GNU C Library; if not, see
|
|
||||||
+ <https://www.gnu.org/licenses/>. */
|
|
||||||
+
|
|
||||||
+#include <alloca.h>
|
|
||||||
+#include <stdint.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <unistd.h>
|
|
||||||
+#include <memcopy.h>
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <atomic.h>
|
|
||||||
+
|
|
||||||
+struct msort_param
|
|
||||||
+{
|
|
||||||
+ size_t s;
|
|
||||||
+ size_t var;
|
|
||||||
+ __compar_d_fn_t cmp;
|
|
||||||
+ void *arg;
|
|
||||||
+ char *t;
|
|
||||||
+};
|
|
||||||
+static void msort_with_tmp (const struct msort_param *p, void *b, size_t n);
|
|
||||||
+
|
|
||||||
+static void
|
|
||||||
+msort_with_tmp (const struct msort_param *p, void *b, size_t n)
|
|
||||||
+{
|
|
||||||
+ char *b1, *b2;
|
|
||||||
+ size_t n1, n2;
|
|
||||||
+
|
|
||||||
+ if (n <= 1)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ n1 = n / 2;
|
|
||||||
+ n2 = n - n1;
|
|
||||||
+ b1 = b;
|
|
||||||
+ b2 = (char *) b + (n1 * p->s);
|
|
||||||
+
|
|
||||||
+ msort_with_tmp (p, b1, n1);
|
|
||||||
+ msort_with_tmp (p, b2, n2);
|
|
||||||
+
|
|
||||||
+ char *tmp = p->t;
|
|
||||||
+ const size_t s = p->s;
|
|
||||||
+ __compar_d_fn_t cmp = p->cmp;
|
|
||||||
+ void *arg = p->arg;
|
|
||||||
+ switch (p->var)
|
|
||||||
+ {
|
|
||||||
+ case 0:
|
|
||||||
+ while (n1 > 0 && n2 > 0)
|
|
||||||
+ {
|
|
||||||
+ if ((*cmp) (b1, b2, arg) <= 0)
|
|
||||||
+ {
|
|
||||||
+ *(uint32_t *) tmp = *(uint32_t *) b1;
|
|
||||||
+ b1 += sizeof (uint32_t);
|
|
||||||
+ --n1;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ *(uint32_t *) tmp = *(uint32_t *) b2;
|
|
||||||
+ b2 += sizeof (uint32_t);
|
|
||||||
+ --n2;
|
|
||||||
+ }
|
|
||||||
+ tmp += sizeof (uint32_t);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case 1:
|
|
||||||
+ while (n1 > 0 && n2 > 0)
|
|
||||||
+ {
|
|
||||||
+ if ((*cmp) (b1, b2, arg) <= 0)
|
|
||||||
+ {
|
|
||||||
+ *(uint64_t *) tmp = *(uint64_t *) b1;
|
|
||||||
+ b1 += sizeof (uint64_t);
|
|
||||||
+ --n1;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ *(uint64_t *) tmp = *(uint64_t *) b2;
|
|
||||||
+ b2 += sizeof (uint64_t);
|
|
||||||
+ --n2;
|
|
||||||
+ }
|
|
||||||
+ tmp += sizeof (uint64_t);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ while (n1 > 0 && n2 > 0)
|
|
||||||
+ {
|
|
||||||
+ unsigned long *tmpl = (unsigned long *) tmp;
|
|
||||||
+ unsigned long *bl;
|
|
||||||
+
|
|
||||||
+ tmp += s;
|
|
||||||
+ if ((*cmp) (b1, b2, arg) <= 0)
|
|
||||||
+ {
|
|
||||||
+ bl = (unsigned long *) b1;
|
|
||||||
+ b1 += s;
|
|
||||||
+ --n1;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ bl = (unsigned long *) b2;
|
|
||||||
+ b2 += s;
|
|
||||||
+ --n2;
|
|
||||||
+ }
|
|
||||||
+ while (tmpl < (unsigned long *) tmp)
|
|
||||||
+ *tmpl++ = *bl++;
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case 3:
|
|
||||||
+ while (n1 > 0 && n2 > 0)
|
|
||||||
+ {
|
|
||||||
+ if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0)
|
|
||||||
+ {
|
|
||||||
+ *(void **) tmp = *(void **) b1;
|
|
||||||
+ b1 += sizeof (void *);
|
|
||||||
+ --n1;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ *(void **) tmp = *(void **) b2;
|
|
||||||
+ b2 += sizeof (void *);
|
|
||||||
+ --n2;
|
|
||||||
+ }
|
|
||||||
+ tmp += sizeof (void *);
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ while (n1 > 0 && n2 > 0)
|
|
||||||
+ {
|
|
||||||
+ if ((*cmp) (b1, b2, arg) <= 0)
|
|
||||||
+ {
|
|
||||||
+ tmp = (char *) __mempcpy (tmp, b1, s);
|
|
||||||
+ b1 += s;
|
|
||||||
+ --n1;
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ tmp = (char *) __mempcpy (tmp, b2, s);
|
|
||||||
+ b2 += s;
|
|
||||||
+ --n2;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (n1 > 0)
|
|
||||||
+ memcpy (tmp, b1, n1 * s);
|
|
||||||
+ memcpy (b, p->t, (n - n2) * s);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+__qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
|
|
||||||
+{
|
|
||||||
+ size_t size = n * s;
|
|
||||||
+ char *tmp = NULL;
|
|
||||||
+ struct msort_param p;
|
|
||||||
+
|
|
||||||
+ /* For large object sizes use indirect sorting. */
|
|
||||||
+ if (s > 32)
|
|
||||||
+ size = 2 * n * sizeof (void *) + s;
|
|
||||||
+
|
|
||||||
+ if (size < 1024)
|
|
||||||
+ /* The temporary array is small, so put it on the stack. */
|
|
||||||
+ p.t = __alloca (size);
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ /* We should avoid allocating too much memory since this might
|
|
||||||
+ have to be backed up by swap space. */
|
|
||||||
+ static long int phys_pages;
|
|
||||||
+ static int pagesize;
|
|
||||||
+
|
|
||||||
+ if (pagesize == 0)
|
|
||||||
+ {
|
|
||||||
+ phys_pages = __sysconf (_SC_PHYS_PAGES);
|
|
||||||
+
|
|
||||||
+ if (phys_pages == -1)
|
|
||||||
+ /* Error while determining the memory size. So let's
|
|
||||||
+ assume there is enough memory. Otherwise the
|
|
||||||
+ implementer should provide a complete implementation of
|
|
||||||
+ the `sysconf' function. */
|
|
||||||
+ phys_pages = (long int) (~0ul >> 1);
|
|
||||||
+
|
|
||||||
+ /* The following determines that we will never use more than
|
|
||||||
+ a quarter of the physical memory. */
|
|
||||||
+ phys_pages /= 4;
|
|
||||||
+
|
|
||||||
+ /* Make sure phys_pages is written to memory. */
|
|
||||||
+ atomic_write_barrier ();
|
|
||||||
+
|
|
||||||
+ pagesize = __sysconf (_SC_PAGESIZE);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Just a comment here. We cannot compute
|
|
||||||
+ phys_pages * pagesize
|
|
||||||
+ and compare the needed amount of memory against this value.
|
|
||||||
+ The problem is that some systems might have more physical
|
|
||||||
+ memory then can be represented with a `size_t' value (when
|
|
||||||
+ measured in bytes. */
|
|
||||||
+
|
|
||||||
+ /* If the memory requirements are too high don't allocate memory. */
|
|
||||||
+ if (size / pagesize > (size_t) phys_pages)
|
|
||||||
+ {
|
|
||||||
+ _quicksort (b, n, s, cmp, arg);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* It's somewhat large, so malloc it. */
|
|
||||||
+ int save = errno;
|
|
||||||
+ tmp = malloc (size);
|
|
||||||
+ __set_errno (save);
|
|
||||||
+ if (tmp == NULL)
|
|
||||||
+ {
|
|
||||||
+ /* Couldn't get space, so use the slower algorithm
|
|
||||||
+ that doesn't need a temporary array. */
|
|
||||||
+ _quicksort (b, n, s, cmp, arg);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ p.t = tmp;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ p.s = s;
|
|
||||||
+ p.var = 4;
|
|
||||||
+ p.cmp = cmp;
|
|
||||||
+ p.arg = arg;
|
|
||||||
+
|
|
||||||
+ if (s > 32)
|
|
||||||
+ {
|
|
||||||
+ /* Indirect sorting. */
|
|
||||||
+ char *ip = (char *) b;
|
|
||||||
+ void **tp = (void **) (p.t + n * sizeof (void *));
|
|
||||||
+ void **t = tp;
|
|
||||||
+ void *tmp_storage = (void *) (tp + n);
|
|
||||||
+
|
|
||||||
+ while ((void *) t < tmp_storage)
|
|
||||||
+ {
|
|
||||||
+ *t++ = ip;
|
|
||||||
+ ip += s;
|
|
||||||
+ }
|
|
||||||
+ p.s = sizeof (void *);
|
|
||||||
+ p.var = 3;
|
|
||||||
+ msort_with_tmp (&p, p.t + n * sizeof (void *), n);
|
|
||||||
+
|
|
||||||
+ /* tp[0] .. tp[n - 1] is now sorted, copy around entries of
|
|
||||||
+ the original array. Knuth vol. 3 (2nd ed.) exercise 5.2-10. */
|
|
||||||
+ char *kp;
|
|
||||||
+ size_t i;
|
|
||||||
+ for (i = 0, ip = (char *) b; i < n; i++, ip += s)
|
|
||||||
+ if ((kp = tp[i]) != ip)
|
|
||||||
+ {
|
|
||||||
+ size_t j = i;
|
|
||||||
+ char *jp = ip;
|
|
||||||
+ memcpy (tmp_storage, ip, s);
|
|
||||||
+
|
|
||||||
+ do
|
|
||||||
+ {
|
|
||||||
+ size_t k = (kp - (char *) b) / s;
|
|
||||||
+ tp[j] = jp;
|
|
||||||
+ memcpy (jp, kp, s);
|
|
||||||
+ j = k;
|
|
||||||
+ jp = kp;
|
|
||||||
+ kp = tp[k];
|
|
||||||
+ }
|
|
||||||
+ while (kp != ip);
|
|
||||||
+
|
|
||||||
+ tp[j] = jp;
|
|
||||||
+ memcpy (jp, tmp_storage, s);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ else
|
|
||||||
+ {
|
|
||||||
+ if ((s & (sizeof (uint32_t) - 1)) == 0
|
|
||||||
+ && ((uintptr_t) b) % __alignof__ (uint32_t) == 0)
|
|
||||||
+ {
|
|
||||||
+ if (s == sizeof (uint32_t))
|
|
||||||
+ p.var = 0;
|
|
||||||
+ else if (s == sizeof (uint64_t)
|
|
||||||
+ && ((uintptr_t) b) % __alignof__ (uint64_t) == 0)
|
|
||||||
+ p.var = 1;
|
|
||||||
+ else if ((s & (sizeof (unsigned long) - 1)) == 0
|
|
||||||
+ && ((uintptr_t) b)
|
|
||||||
+ % __alignof__ (unsigned long) == 0)
|
|
||||||
+ p.var = 2;
|
|
||||||
+ }
|
|
||||||
+ msort_with_tmp (&p, b, n);
|
|
||||||
+ }
|
|
||||||
+ free (tmp);
|
|
||||||
+}
|
|
||||||
+libc_hidden_def (__qsort_r)
|
|
||||||
+weak_alias (__qsort_r, qsort_r)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+void
|
|
||||||
+qsort (void *b, size_t n, size_t s, __compar_fn_t cmp)
|
|
||||||
+{
|
|
||||||
+ return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL);
|
|
||||||
+}
|
|
||||||
+libc_hidden_def (qsort)
|
|
||||||
diff --git a/stdlib/qsort.c b/stdlib/qsort.c
|
|
||||||
index fd32a165e7313c3a..d5f205affc4371cb 100644
|
|
||||||
--- a/stdlib/qsort.c
|
|
||||||
+++ b/stdlib/qsort.c
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
Engineering a sort function; Jon Bentley and M. Douglas McIlroy;
|
|
||||||
Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */
|
|
||||||
|
|
||||||
+#include <alloca.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <memswap.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
@@ -264,8 +265,8 @@ insertion_sort_qsort_partitions (void *const pbase, size_t total_elems,
|
|
||||||
stack size is needed (actually O(1) in this case)! */
|
|
||||||
|
|
||||||
void
|
|
||||||
-__qsort_r (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
- __compar_d_fn_t cmp, void *arg)
|
|
||||||
+_quicksort (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
+ __compar_d_fn_t cmp, void *arg)
|
|
||||||
{
|
|
||||||
char *base_ptr = (char *) pbase;
|
|
||||||
|
|
||||||
@@ -397,12 +398,3 @@ __qsort_r (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
insertion_sort_qsort_partitions (pbase, total_elems, size, swap_type, cmp,
|
|
||||||
arg);
|
|
||||||
}
|
|
||||||
-libc_hidden_def (__qsort_r)
|
|
||||||
-weak_alias (__qsort_r, qsort_r)
|
|
||||||
-
|
|
||||||
-void
|
|
||||||
-qsort (void *b, size_t n, size_t s, __compar_fn_t cmp)
|
|
||||||
-{
|
|
||||||
- return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL);
|
|
||||||
-}
|
|
||||||
-libc_hidden_def (qsort)
|
|
@ -1,166 +0,0 @@
|
|||||||
Revert "stdlib: Implement introsort for qsort (BZ 19305)"
|
|
||||||
|
|
||||||
This reverts commit 274a46c9b25ab733a1fb9fb1497f1beecae30193.
|
|
||||||
|
|
||||||
diff --git a/stdlib/qsort.c b/stdlib/qsort.c
|
|
||||||
index d5f205affc4371cb..80706b335722f721 100644
|
|
||||||
--- a/stdlib/qsort.c
|
|
||||||
+++ b/stdlib/qsort.c
|
|
||||||
@@ -98,7 +98,6 @@ typedef struct
|
|
||||||
{
|
|
||||||
char *lo;
|
|
||||||
char *hi;
|
|
||||||
- size_t depth;
|
|
||||||
} stack_node;
|
|
||||||
|
|
||||||
/* The stack needs log (total_elements) entries (we could even subtract
|
|
||||||
@@ -108,85 +107,22 @@ typedef struct
|
|
||||||
enum { STACK_SIZE = CHAR_BIT * sizeof (size_t) };
|
|
||||||
|
|
||||||
static inline stack_node *
|
|
||||||
-push (stack_node *top, char *lo, char *hi, size_t depth)
|
|
||||||
+push (stack_node *top, char *lo, char *hi)
|
|
||||||
{
|
|
||||||
top->lo = lo;
|
|
||||||
top->hi = hi;
|
|
||||||
- top->depth = depth;
|
|
||||||
return ++top;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline stack_node *
|
|
||||||
-pop (stack_node *top, char **lo, char **hi, size_t *depth)
|
|
||||||
+pop (stack_node *top, char **lo, char **hi)
|
|
||||||
{
|
|
||||||
--top;
|
|
||||||
*lo = top->lo;
|
|
||||||
*hi = top->hi;
|
|
||||||
- *depth = top->depth;
|
|
||||||
return top;
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* NB: N is inclusive bound for BASE. */
|
|
||||||
-static inline void
|
|
||||||
-siftdown (void *base, size_t size, size_t k, size_t n,
|
|
||||||
- enum swap_type_t swap_type, __compar_d_fn_t cmp, void *arg)
|
|
||||||
-{
|
|
||||||
- while (k <= n / 2)
|
|
||||||
- {
|
|
||||||
- size_t j = 2 * k;
|
|
||||||
- if (j < n && cmp (base + (j * size), base + ((j + 1) * size), arg) < 0)
|
|
||||||
- j++;
|
|
||||||
-
|
|
||||||
- if (cmp (base + (k * size), base + (j * size), arg) >= 0)
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- do_swap (base + (size * j), base + (k * size), size, swap_type);
|
|
||||||
- k = j;
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static inline void
|
|
||||||
-heapify (void *base, size_t size, size_t n, enum swap_type_t swap_type,
|
|
||||||
- __compar_d_fn_t cmp, void *arg)
|
|
||||||
-{
|
|
||||||
- size_t k = n / 2;
|
|
||||||
- while (1)
|
|
||||||
- {
|
|
||||||
- siftdown (base, size, k, n, swap_type, cmp, arg);
|
|
||||||
- if (k-- == 0)
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/* A non-recursive heapsort, used on introsort implementation as a fallback
|
|
||||||
- routine with worst-case performance of O(nlog n) and worst-case space
|
|
||||||
- complexity of O(1). It sorts the array starting at BASE and ending at
|
|
||||||
- END, with each element of SIZE bytes. The SWAP_TYPE is the callback
|
|
||||||
- function used to swap elements, and CMP is the function used to compare
|
|
||||||
- elements. */
|
|
||||||
-static void
|
|
||||||
-heapsort_r (void *base, void *end, size_t size, enum swap_type_t swap_type,
|
|
||||||
- __compar_d_fn_t cmp, void *arg)
|
|
||||||
-{
|
|
||||||
- const size_t count = ((uintptr_t) end - (uintptr_t) base) / size;
|
|
||||||
-
|
|
||||||
- if (count < 2)
|
|
||||||
- return;
|
|
||||||
-
|
|
||||||
- size_t n = count - 1;
|
|
||||||
-
|
|
||||||
- /* Build the binary heap, largest value at the base[0]. */
|
|
||||||
- heapify (base, size, n, swap_type, cmp, arg);
|
|
||||||
-
|
|
||||||
- /* On each iteration base[0:n] is the binary heap, while base[n:count]
|
|
||||||
- is sorted. */
|
|
||||||
- while (n > 0)
|
|
||||||
- {
|
|
||||||
- do_swap (base, base + (n * size), size, swap_type);
|
|
||||||
- n--;
|
|
||||||
- siftdown (base, size, 0, n, swap_type, cmp, arg);
|
|
||||||
- }
|
|
||||||
-}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
insertion_sort_qsort_partitions (void *const pbase, size_t total_elems,
|
|
||||||
@@ -272,7 +208,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
|
|
||||||
const size_t max_thresh = MAX_THRESH * size;
|
|
||||||
|
|
||||||
- if (total_elems <= 1)
|
|
||||||
+ if (total_elems == 0)
|
|
||||||
/* Avoid lossage with unsigned arithmetic below. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
@@ -284,26 +220,15 @@ _quicksort (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
else
|
|
||||||
swap_type = SWAP_BYTES;
|
|
||||||
|
|
||||||
- /* Maximum depth before quicksort switches to heapsort. */
|
|
||||||
- size_t depth = 2 * (sizeof (size_t) * CHAR_BIT - 1
|
|
||||||
- - __builtin_clzl (total_elems));
|
|
||||||
-
|
|
||||||
if (total_elems > MAX_THRESH)
|
|
||||||
{
|
|
||||||
char *lo = base_ptr;
|
|
||||||
char *hi = &lo[size * (total_elems - 1)];
|
|
||||||
stack_node stack[STACK_SIZE];
|
|
||||||
- stack_node *top = push (stack, NULL, NULL, depth);
|
|
||||||
+ stack_node *top = stack + 1;
|
|
||||||
|
|
||||||
while (stack < top)
|
|
||||||
{
|
|
||||||
- if (depth == 0)
|
|
||||||
- {
|
|
||||||
- heapsort_r (lo, hi, size, swap_type, cmp, arg);
|
|
||||||
- top = pop (top, &lo, &hi, &depth);
|
|
||||||
- continue;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
char *left_ptr;
|
|
||||||
char *right_ptr;
|
|
||||||
|
|
||||||
@@ -367,7 +292,7 @@ _quicksort (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
{
|
|
||||||
if ((size_t) (hi - left_ptr) <= max_thresh)
|
|
||||||
/* Ignore both small partitions. */
|
|
||||||
- top = pop (top, &lo, &hi, &depth);
|
|
||||||
+ top = pop (top, &lo, &hi);
|
|
||||||
else
|
|
||||||
/* Ignore small left partition. */
|
|
||||||
lo = left_ptr;
|
|
||||||
@@ -378,13 +303,13 @@ _quicksort (void *const pbase, size_t total_elems, size_t size,
|
|
||||||
else if ((right_ptr - lo) > (hi - left_ptr))
|
|
||||||
{
|
|
||||||
/* Push larger left partition indices. */
|
|
||||||
- top = push (top, lo, right_ptr, depth - 1);
|
|
||||||
+ top = push (top, lo, right_ptr);
|
|
||||||
lo = left_ptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Push larger right partition indices. */
|
|
||||||
- top = push (top, left_ptr, hi, depth - 1);
|
|
||||||
+ top = push (top, left_ptr, hi);
|
|
||||||
hi = right_ptr;
|
|
||||||
}
|
|
||||||
}
|
|
22
glibc.spec
22
glibc.spec
@ -1,4 +1,4 @@
|
|||||||
%global glibcsrcdir glibc-2.38.9000-234-g5dd3bda59c
|
%global glibcsrcdir glibc-2.38.9000-244-gd1dcb565a1
|
||||||
%global glibcversion 2.38.9000
|
%global glibcversion 2.38.9000
|
||||||
# Pre-release tarballs are pulled in from git using a command that is
|
# Pre-release tarballs are pulled in from git using a command that is
|
||||||
# effectively:
|
# effectively:
|
||||||
@ -159,7 +159,7 @@ Version: %{glibcversion}
|
|||||||
# - It allows using the Release number without the %%dist tag in the dependency
|
# - It allows using the Release number without the %%dist tag in the dependency
|
||||||
# generator to make the generated requires interchangeable between Rawhide
|
# generator to make the generated requires interchangeable between Rawhide
|
||||||
# and ELN (.elnYY < .fcXX).
|
# and ELN (.elnYY < .fcXX).
|
||||||
%global baserelease 19
|
%global baserelease 20
|
||||||
Release: %{baserelease}%{?dist}
|
Release: %{baserelease}%{?dist}
|
||||||
|
|
||||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||||
@ -231,9 +231,7 @@ Patch13: glibc-fedora-localedata-rh61908.patch
|
|||||||
Patch17: glibc-cs-path.patch
|
Patch17: glibc-cs-path.patch
|
||||||
Patch23: glibc-python3.patch
|
Patch23: glibc-python3.patch
|
||||||
Patch24: glibc-rh2244688.patch
|
Patch24: glibc-rh2244688.patch
|
||||||
Patch25: glibc-rh2248502-1.patch
|
Patch25: glibc-rh2244992.patch
|
||||||
Patch26: glibc-rh2248502-2.patch
|
|
||||||
Patch27: glibc-rh2244992.patch
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Continued list of core "glibc" package information:
|
# Continued list of core "glibc" package information:
|
||||||
@ -2204,6 +2202,20 @@ update_gconv_modules_cache ()
|
|||||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Nov 11 2023 Florian Weimer <fweimer@redhat.com> - 2.38.9000-20
|
||||||
|
- Drop glibc-rh2248502-*.patch, workaround applied upstream
|
||||||
|
- Auto-sync with upstream branch master,
|
||||||
|
commit d1dcb565a1fb5829f9476a1438c30eccc4027d04:
|
||||||
|
- Fix type typo in “String/Array Conventions” doc
|
||||||
|
- stdlib: Avoid element self-comparisons in qsort (#2248502)
|
||||||
|
- elf: Add glibc.mem.decorate_maps tunable
|
||||||
|
- linux: Decorate __libc_fatal error buffer
|
||||||
|
- assert: Decorate error message buffer
|
||||||
|
- malloc: Decorate malloc maps
|
||||||
|
- nptl: Decorate thread stack on pthread_create
|
||||||
|
- support: Add support_set_vma_name
|
||||||
|
- linux: Add PR_SET_VMA_ANON_NAME support
|
||||||
|
|
||||||
* Wed Nov 8 2023 Florian Weimer <fweimer@redhat.com> - 2.38.9000-19
|
* Wed Nov 8 2023 Florian Weimer <fweimer@redhat.com> - 2.38.9000-19
|
||||||
- Fix force-first handling in dlclose, take two (#2244992, #2246048)
|
- Fix force-first handling in dlclose, take two (#2244992, #2246048)
|
||||||
|
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (glibc-2.38.9000-234-g5dd3bda59c.tar.xz) = aab645c2794c3a60d2748b3c2e91779b19f2393103f9cad74688c962ad6020c00b19eae51766fc829533039e74feeb4f7f9199d77450df31e42c69cfe7529c91
|
SHA512 (glibc-2.38.9000-244-gd1dcb565a1.tar.xz) = 74d23268abb91447d74906ae477f926baa2f54a95d87fc18d8972a976524987e98f6141f3767406aef6293d2ef7f7bc16cfedaacd2d33bca207253ec7073c915
|
||||||
|
Loading…
Reference in New Issue
Block a user