[dm-devel] [PATCH v4 2/5] libmultipath: modifications for msort.c
mwilck at suse.com
mwilck at suse.com
Fri Aug 26 18:05:52 UTC 2022
From: Martin Wilck <mwilck at suse.com>
We don't want to fallback to qsort if memory is tight, as libc's
routine does. Other than that, compile error fixes.
Signed-off-by: Martin Wilck <mwilck at suse.com>
---
libmultipath/Makefile | 2 +-
libmultipath/msort.c | 88 ++++++++++++-------------------------------
libmultipath/msort.h | 6 +++
3 files changed, 32 insertions(+), 64 deletions(-)
create mode 100644 libmultipath/msort.h
diff --git a/libmultipath/Makefile b/libmultipath/Makefile
index fb03200..a70acab 100644
--- a/libmultipath/Makefile
+++ b/libmultipath/Makefile
@@ -64,7 +64,7 @@ OBJS-O := parser.o vector.o devmapper.o \
log.o configure.o structs_vec.o sysfs.o \
lock.o file.o wwids.o prioritizers/alua_rtpg.o prkey.o \
io_err_stat.o dm-generic.o generic.o nvme-lib.o \
- libsg.o valid.o strbuf.o
+ libsg.o valid.o strbuf.o msort.o
OBJS := $(OBJS-O) $(OBJS-U)
diff --git a/libmultipath/msort.c b/libmultipath/msort.c
index cbe9a4a..2963486 100644
--- a/libmultipath/msort.c
+++ b/libmultipath/msort.c
@@ -21,9 +21,11 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <memcopy.h>
+#include <string.h>
#include <errno.h>
-#include <atomic.h>
+#include "msort.h"
+
+typedef int(*__compar_d_fn_t)(const void *, const void *, void *);
struct msort_param
{
@@ -140,13 +142,13 @@ msort_with_tmp (const struct msort_param *p, void *b, size_t n)
{
if ((*cmp) (b1, b2, arg) <= 0)
{
- tmp = (char *) __mempcpy (tmp, b1, s);
+ tmp = (char *) mempcpy (tmp, b1, s);
b1 += s;
--n1;
}
else
{
- tmp = (char *) __mempcpy (tmp, b2, s);
+ tmp = (char *) mempcpy (tmp, b2, s);
b2 += s;
--n2;
}
@@ -160,8 +162,8 @@ msort_with_tmp (const struct msort_param *p, void *b, size_t n)
}
-void
-__qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
+static void
+msort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
{
size_t size = n * s;
char *tmp = NULL;
@@ -173,60 +175,15 @@ __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
if (size < 1024)
/* The temporary array is small, so put it on the stack. */
- p.t = __alloca (size);
+ 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);
+ 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;
- }
+ return;
p.t = tmp;
}
@@ -281,15 +238,15 @@ __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
else
{
if ((s & (sizeof (uint32_t) - 1)) == 0
- && ((char *) b - (char *) 0) % __alignof__ (uint32_t) == 0)
+ && ((unsigned long) b) % __alignof__ (uint32_t) == 0)
{
if (s == sizeof (uint32_t))
p.var = 0;
else if (s == sizeof (uint64_t)
- && ((char *) b - (char *) 0) % __alignof__ (uint64_t) == 0)
+ && ((unsigned long) b) % __alignof__ (uint64_t) == 0)
p.var = 1;
else if ((s & (sizeof (unsigned long) - 1)) == 0
- && ((char *) b - (char *) 0)
+ && ((unsigned long) b)
% __alignof__ (unsigned long) == 0)
p.var = 2;
}
@@ -297,13 +254,18 @@ __qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
}
free (tmp);
}
-libc_hidden_def (__qsort_r)
-weak_alias (__qsort_r, qsort_r)
-
+/*
+ * glibc apparently doesn't use -Wcast-function-type.
+ * If this is safe for them, it should be for us, too.
+ */
+#pragma GCC diagnostic push
+#if __GNUC__ >= 8
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
void
-qsort (void *b, size_t n, size_t s, __compar_fn_t cmp)
+msort (void *b, size_t n, size_t s, __compar_fn_t cmp)
{
- return __qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL);
+ return msort_r (b, n, s, (__compar_d_fn_t)cmp, NULL);
}
-libc_hidden_def (qsort)
+#pragma GCC diagnostic pop
diff --git a/libmultipath/msort.h b/libmultipath/msort.h
new file mode 100644
index 0000000..caef9b6
--- /dev/null
+++ b/libmultipath/msort.h
@@ -0,0 +1,6 @@
+#ifndef __MSORT_H
+#define __MSORT_H
+typedef int(*__compar_fn_t)(const void *, const void *);
+void msort (void *b, size_t n, size_t s, __compar_fn_t cmp);
+
+#endif
--
2.37.1
More information about the dm-devel
mailing list