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