git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[DEMO][PATCH v2 6/5] compat: add a qsort_s() implementation based on GNU's qsort_r(1)

From
René Scharfe <l.s.r@web.de>
Date
Jan 22, 2017, 18:02 UTC
Message-ID
<9f8b564d-ec9f-abc9-77f6-aa84c6e78b7a@web.de>
In-Reply-To
<67ac53cd-3fc0-8bd0-30f4-129281c3090f@web.de>

Implement qsort_s() as a wrapper to the GNU version of qsort_r(1) and use it on Linux. Performance increases slightly:

Test HEAD^ HEAD -------------------------------------------------------------------- 0071.2: sort(1) 0.10(0.20+0.02) 0.10(0.21+0.01) +0.0% 0071.3: string_list_sort() 0.17(0.15+0.01) 0.16(0.15+0.01) -5.9%

Additionally the unstripped size of compat/qsort_s.o falls from 24576 to 16544 bytes in my build.

IMHO these savings aren't worth the increased complexity of having to
support two implementations.
---
 Makefile         |  6 ++++++
 compat/qsort_s.c | 18 ++++++++++++++++++
 config.mak.uname |  1 +
 3 files changed, 25 insertions(+)
diff --git a/Makefile b/Makefile
index 53ecc84e28..46db1c773f 100644
--- a/Makefile
+++ b/Makefile
@@ -282,6 +282,9 @@ all::
 # Define HAVE_ISO_QSORT_S if your platform provides a qsort_s() that's
 # compatible with the one described in C11 Annex K.
 #
+# Define HAVE_GNU_QSORT_R if your platform provides a qsort_r() that's
+# compatible with the one introduced with glibc 2.8.
+#
 # Define UNRELIABLE_FSTAT if your system's fstat does not return the same
 # information on a not yet closed file that lstat would return for the same
 # file after it was closed.
@@ -1426,6 +1429,9 @@ ifdef HAVE_ISO_QSORT_S
 else
 	COMPAT_OBJS += compat/qsort_s.o
 endif
+ifdef HAVE_GNU_QSORT_R
+	COMPAT_CFLAGS += -DHAVE_GNU_QSORT_R
+endif
 ifdef RUNTIME_PREFIX
 	COMPAT_CFLAGS += -DRUNTIME_PREFIX
 endif
diff --git a/compat/qsort_s.c b/compat/qsort_s.c
index 52d1f0a73d..763ee1faae 100644
--- a/compat/qsort_s.c
+++ b/compat/qsort_s.c
@@ -1,5 +1,21 @@
 #include "../git-compat-util.h"
 
+#if defined HAVE_GNU_QSORT_R
+
+int git_qsort_s(void *b, size_t n, size_t s,
+		int (*cmp)(const void *, const void *, void *), void *ctx)
+{
+	if (!n)
+		return 0;
+	if (!b || !cmp)
+		return -1;
+
+	qsort_r(b, n, s, cmp, ctx);
+	return 0;
+}
+
+#else
+
 /*
  * A merge sort implementation, simplified from the qsort implementation
  * by Mike Haertel, which is a part of the GNU C Library.
@@ -67,3 +83,5 @@ int git_qsort_s(void *b, size_t n, size_t s,
 	}
 	return 0;
 }
+
+#endif
diff --git a/config.mak.uname b/config.mak.uname
index 447f36ac2e..a1858f54ff 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -37,6 +37,7 @@ ifeq ($(uname_S),Linux)
 	NEEDS_LIBRT = YesPlease
 	HAVE_GETDELIM = YesPlease
 	SANE_TEXT_GREP=-a
+	HAVE_GNU_QSORT_R = YesPlease
 endif
 ifeq ($(uname_S),GNU/kFreeBSD)
 	HAVE_ALLOCA_H = YesPlease
-- 
2.11.0
Previous: René ScharfeNext: Junio C Hamano
Message 7 of 18 in “string-list: make string_list_sort() reentrant”
  1. 0/5 string-list: make string_list_sort() reentrantRené Scharfe, Jan 22, 2017
  2. 1/5 compat: add qsort_s()René Scharfe, Jan 22, 2017
  3. 3/5 perf: add basic sort performance testRené Scharfe, Jan 22, 2017
  4. 4/5 string-list: use QSORT_S in string_list_sort()René Scharfe, Jan 22, 2017
  5. 5/5 ref-filter: use QSORT_S in ref_array_sort()René Scharfe, Jan 22, 2017
  6. 2/5 add QSORT_SRené Scharfe, Jan 22, 2017
  7. [DEMO][PATCH v2 6/5] compat: add a qsort_s() implementation based on GNU's qsort_r(1)René Scharfe, Jan 22, 2017
  8. Junio C HamanoJan 23, 2017
  9. René ScharfeJan 24, 2017
  10. Jeff KingJan 24, 2017
  11. René ScharfeJan 25, 2017
  12. Jeff KingJan 25, 2017
  13. Johannes SchindelinJan 26, 2017
  14. Jeff KingJan 23, 2017
  15. Johannes SchindelinJan 24, 2017
  16. Jeff KingJan 24, 2017
  17. René ScharfeJan 24, 2017
  18. Jeff KingJan 24, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.