From 7067f4753f706b5110a0eb56ce0e827e155fadf4 Mon Sep 17 00:00:00 2001 From: Brian Barrett Date: Sun, 26 Jun 2005 23:11:37 +0000 Subject: [PATCH] A bunch of fixes from trying to get running on Solaris and Linux PPC64 * If we are on solaris, don't use the system qsort(), as it appears to be broken in 64 bit mode on Solaris 8 (there are bugs about this in SunSolve). Instead, use ompi_qsort(), which is taken from FreeBSD. A #define in ompi_config_bottom.h makes this invisible to most of the OMPI source tree. * Fix memory badness in ompi_progress_register where we were reallocing the array to be number of elements long instead of number of elements * sizeof(element). Found while using bcheck to track down our problems in 64 bit on big endian machines. * The debugging output code in session_dir.c could pass NULL as a value for a %s, which will turn into "(null)" automagically on glibc, but causes segfaults for older libcs (like those on Solaris). Check for this case in session_dir.c and don't pass NULL as a %s value into ompi_output(). * Fix missing header file in convertor.c This commit was SVN r6186. --- acinclude.m4 | 1 + config/ompi_check_broken_qsort.m4 | 37 +++++++ configure.ac | 2 + include/ompi_config_bottom.h | 5 + src/datatype/convertor.c | 4 + src/runtime/ompi_progress.c | 2 +- src/util/Makefile.am | 6 +- src/util/qsort.c | 173 ++++++++++++++++++++++++++++++ src/util/qsort.h | 22 ++++ src/util/session_dir.c | 16 ++- 10 files changed, 260 insertions(+), 8 deletions(-) create mode 100644 config/ompi_check_broken_qsort.m4 create mode 100644 src/util/qsort.c create mode 100644 src/util/qsort.h diff --git a/acinclude.m4 b/acinclude.m4 index 6eba066c3f..4d9f87d476 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -47,6 +47,7 @@ sinclude(config/ompi_try_assemble.m4) sinclude(config/ompi_config_asm.m4) sinclude(config/ompi_case_sensitive_fs_setup.m4) +sinclude(config/ompi_check_broken_qsort.m4) sinclude(config/ompi_check_optflags.m4) sinclude(config/ompi_check_icc.m4) sinclude(config/ompi_config_subdir.m4) diff --git a/config/ompi_check_broken_qsort.m4 b/config/ompi_check_broken_qsort.m4 new file mode 100644 index 0000000000..5a0c428e8a --- /dev/null +++ b/config/ompi_check_broken_qsort.m4 @@ -0,0 +1,37 @@ +dnl -*- shell-script -*- +dnl +dnl Copyright (c) 2004-2005 The Trustees of Indiana University. +dnl All rights reserved. +dnl Copyright (c) 2004-2005 The Trustees of the University of Tennessee. +dnl All rights reserved. +dnl Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, +dnl University of Stuttgart. All rights reserved. +dnl Copyright (c) 2004-2005 The Regents of the University of California. +dnl All rights reserved. +dnl $COPYRIGHT$ +dnl +dnl Additional copyrights may follow +dnl +dnl $HEADER$ +dnl + +AC_DEFUN([OMPI_CHECK_BROKEN_QSORT],[ + AC_MSG_CHECKING([for broken qsort]) + + result= + define_result=0 + case "$host" in + *solaris*) + result="yes (solaris)" + define_result=1 + ;; + *) + result="no" + define_result=0 + ;; + esac + + AC_MSG_RESULT([$result]) + AC_DEFINE_UNQUOTED([OMPI_HAVE_BROKEN_QSORT], [$define_result], + [whether qsort is broken or not]) +unset result define_result])dnl diff --git a/configure.ac b/configure.ac index d838bd61cf..cecb6badec 100644 --- a/configure.ac +++ b/configure.ac @@ -1131,6 +1131,8 @@ AC_WORDS_BIGENDIAN AC_CHECK_SIZEOF(pid_t) +OMPI_CHECK_BROKEN_QSORT + # all: SYSV semaphores # all: SYSV shared memory # all: size of FD_SET diff --git a/include/ompi_config_bottom.h b/include/ompi_config_bottom.h index 0dff5b20b6..c2b0eb1fbb 100644 --- a/include/ompi_config_bottom.h +++ b/include/ompi_config_bottom.h @@ -308,6 +308,11 @@ typedef long long bool; # define vsnprintf ompi_vsnprintf #endif +#if OMPI_HAVE_BROKEN_QSORT +#include "util/qsort.h" +#define qsort ompi_qsort +#endif + /* * Define __func__-preprocessor directive if the compiler does not * already define it. Define it to __FILE__ so that we at least have diff --git a/src/datatype/convertor.c b/src/datatype/convertor.c index 09062d7007..b2f652cfad 100644 --- a/src/datatype/convertor.c +++ b/src/datatype/convertor.c @@ -17,6 +17,10 @@ #include "ompi_config.h" +#ifdef HAVE_STRINGS_H +#include +#endif + #include "datatype/datatype.h" #include "datatype/convertor.h" #include "datatype/datatype_internal.h" diff --git a/src/runtime/ompi_progress.c b/src/runtime/ompi_progress.c index 549be1f8ac..1b41cb574f 100644 --- a/src/runtime/ompi_progress.c +++ b/src/runtime/ompi_progress.c @@ -257,7 +257,7 @@ ompi_progress_register(ompi_progress_callback_t cb) /* see if we need to allocate more space */ if (callbacks_len + 1 > callbacks_size) { ompi_progress_callback_t *tmp; - tmp = realloc(callbacks, callbacks_size + 4); + tmp = realloc(callbacks, sizeof(ompi_progress_callback_t) * (callbacks_size + 4)); if (tmp == NULL) { ret = OMPI_ERR_TEMP_OUT_OF_RESOURCE; goto cleanup; diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 2426cfb852..46f19d9ee0 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -49,7 +49,8 @@ headers = \ stacktrace.h \ daemon_init.h \ universe_setup_file_io.h \ - strncpy.h + strncpy.h \ + qsort.h libompiutil_la_SOURCES = \ $(headers) \ @@ -76,7 +77,8 @@ libompiutil_la_SOURCES = \ stacktrace.c \ daemon_init.c \ universe_setup_file_io.c \ - strncpy.c + strncpy.c \ + qsort.c # Conditionally install the header files diff --git a/src/util/qsort.c b/src/util/qsort.c new file mode 100644 index 0000000000..24a9e692d9 --- /dev/null +++ b/src/util/qsort.c @@ -0,0 +1,173 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ompi_config.h" +#include "util/qsort.h" + +#include + +typedef int cmp_t(const void *, const void *); +static inline char *med3(char *, char *, char *, cmp_t *, void *); +static inline void swapfunc(char *, char *, int, int); + +#define min(a, b) (a) < (b) ? a : b + +/* + * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". + */ +#define swapcode(TYPE, parmi, parmj, n) { \ + long i = (n) / sizeof (TYPE); \ + TYPE *pi = (TYPE *) (parmi); \ + TYPE *pj = (TYPE *) (parmj); \ + do { \ + TYPE t = *pi; \ + *pi++ = *pj; \ + *pj++ = t; \ + } while (--i > 0); \ +} + +#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ + es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; + +static inline void +swapfunc(a, b, n, swaptype) + char *a, *b; + int n, swaptype; +{ + if(swaptype <= 1) + swapcode(long, a, b, n) + else + swapcode(char, a, b, n) +} + +#define swap(a, b) \ + if (swaptype == 0) { \ + long t = *(long *)(a); \ + *(long *)(a) = *(long *)(b); \ + *(long *)(b) = t; \ + } else \ + swapfunc(a, b, es, swaptype) + +#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) + +#define CMP(t, x, y) (cmp((x), (y))) + +static inline char * +med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk) +{ + return CMP(thunk, a, b) < 0 ? + (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) + :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); +} + +#define thunk NULL +void +ompi_qsort(void *a, size_t n, size_t es, cmp_t *cmp) +{ + char *pa, *pb, *pc, *pd, *pl, *pm, *pn; + int d, r, swaptype, swap_cnt; + +loop: SWAPINIT(a, es); + swap_cnt = 0; + if (n < 7) { + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + pm = (char *)a + (n / 2) * es; + if (n > 7) { + pl = a; + pn = (char *)a + (n - 1) * es; + if (n > 40) { + d = (n / 8) * es; + pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); + pm = med3(pm - d, pm, pm + d, cmp, thunk); + pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); + } + pm = med3(pl, pm, pn, cmp, thunk); + } + swap(a, pm); + pa = pb = (char *)a + es; + + pc = pd = (char *)a + (n - 1) * es; + for (;;) { + while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pa, pb); + pa += es; + } + pb += es; + } + while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { + if (r == 0) { + swap_cnt = 1; + swap(pc, pd); + pd -= es; + } + pc -= es; + } + if (pb > pc) + break; + swap(pb, pc); + swap_cnt = 1; + pb += es; + pc -= es; + } + if (swap_cnt == 0) { /* Switch to insertion sort */ + for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) + for (pl = pm; + pl > (char *)a && CMP(thunk, pl - es, pl) > 0; + pl -= es) + swap(pl, pl - es); + return; + } + + pn = (char *)a + n * es; + r = (int) min(pa - (char *)a, pb - pa); + vecswap(a, pb - r, r); + r = (int) (min((char*) (pd - pc), (char*) (pn - pd - es))); + vecswap(pb, pn - r, r); + if ((size_t) (r = pb - pa) > es) + ompi_qsort(a, r / es, es, cmp); + if ((size_t) (r = pd - pc) > es) { + /* Iterate rather than recurse to save stack space */ + a = pn - r; + n = r / es; + goto loop; + } +/* qsort(pn - r, r / es, es, cmp);*/ +} diff --git a/src/util/qsort.h b/src/util/qsort.h new file mode 100644 index 0000000000..a4b5f65fb9 --- /dev/null +++ b/src/util/qsort.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2004-2005 The Trustees of Indiana University. + * All rights reserved. + * Copyright (c) 2004-2005 The Trustees of the University of Tennessee. + * All rights reserved. + * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, + * University of Stuttgart. All rights reserved. + * Copyright (c) 2004-2005 The Regents of the University of California. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + */ + +#ifndef OMPI_QSORT_H +#define OMPI_QSORT_H + +void ompi_qsort(void *a, size_t n, size_t es, int (*cmp)(const void *, const void*)); + +#endif diff --git a/src/util/session_dir.c b/src/util/session_dir.c index 2998436fec..795c67817c 100644 --- a/src/util/session_dir.c +++ b/src/util/session_dir.c @@ -68,6 +68,7 @@ static bool orte_is_empty(char *pathname); #define OMPI_DEFAULT_TMPDIR "/tmp" #endif +#define OMPI_PRINTF_FIX_STRING(a) ((NULL == a) ? "(null)" : a) static int orte_check_dir(bool create, char *directory) { @@ -313,11 +314,16 @@ int orte_session_dir(bool create, char *prfx, char *usr, char *hostid, } if (orte_debug_flag) { - ompi_output(0, "procdir: %s", orte_process_info.proc_session_dir); - ompi_output(0, "jobdir: %s", orte_process_info.job_session_dir); - ompi_output(0, "unidir: %s", orte_process_info.universe_session_dir); - ompi_output(0, "top: %s", orte_process_info.top_session_dir); - ompi_output(0, "tmp: %s", orte_process_info.tmpdir_base); + ompi_output(0, "procdir: %s", + OMPI_PRINTF_FIX_STRING(orte_process_info.proc_session_dir)); + ompi_output(0, "jobdir: %s", + OMPI_PRINTF_FIX_STRING(orte_process_info.job_session_dir)); + ompi_output(0, "unidir: %s", + OMPI_PRINTF_FIX_STRING(orte_process_info.universe_session_dir)); + ompi_output(0, "top: %s", + OMPI_PRINTF_FIX_STRING(orte_process_info.top_session_dir)); + ompi_output(0, "tmp: %s", + OMPI_PRINTF_FIX_STRING(orte_process_info.tmpdir_base)); } CLEANUP: