summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--rts/ProfHeap.c21
2 files changed, 17 insertions, 6 deletions
diff --git a/configure.ac b/configure.ac
index 38289862b9..7b8b747b56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1020,7 +1020,7 @@ FP_CHECK_FUNC([GetModuleFileName],
dnl ** check for more functions
dnl ** The following have been verified to be used in ghc/, but might be used somewhere else, too.
-AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity sched_getaffinity setlocale])
+AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity sched_getaffinity setlocale uselocale])
dnl ** On OS X 10.4 (at least), time.h doesn't declare ctime_r if
dnl ** _POSIX_C_SOURCE is defined
diff --git a/rts/ProfHeap.c b/rts/ProfHeap.c
index e9d9dd364e..82d9059f24 100644
--- a/rts/ProfHeap.c
+++ b/rts/ProfHeap.c
@@ -52,6 +52,10 @@ static char *hp_filename; /* heap profile (hp2ps style) log file */
* As an exception for Darwin, this comes through the <xlocale.h> header instead
* of <locale.h>.
*
+ * On platforms which don't have uselocale(3), we fall back to setlocale() which
+ * mutates the global state. This is of course not thread-safe but is better
+ * than nothing.
+ *
* On Windows, a different _locale_t opaque type does exist, but isn't directly
* usable without special-casing all printf() and related calls, which I'm not
* motivated to trawl through as I don't even have a Windows box to test on.
@@ -63,14 +67,16 @@ static char *hp_filename; /* heap profile (hp2ps style) log file */
#if defined(mingw32_HOST_OS)
static int prof_locale_per_thread = -1;
static const char *saved_locale = NULL;
-#else
+#elif defined(HAVE_USELOCALE)
static locale_t prof_locale = 0, saved_locale = 0;
+#else
+static char *saved_locale = NULL;
#endif
STATIC_INLINE void
init_prof_locale( void )
{
-#if !defined(mingw32_HOST_OS)
+#if defined(HAVE_USELOCALE)
if (! prof_locale) {
prof_locale = newlocale(LC_NUMERIC_MASK, "POSIX", 0);
if (! prof_locale) {
@@ -84,7 +90,7 @@ init_prof_locale( void )
STATIC_INLINE void
free_prof_locale( void )
{
-#if !defined(mingw32_HOST_OS)
+#if defined(HAVE_USELOCALE)
if (prof_locale) {
freelocale(prof_locale);
prof_locale = 0;
@@ -99,8 +105,11 @@ set_prof_locale( void )
prof_locale_per_thread = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
saved_locale = setlocale(LC_NUMERIC, NULL);
setlocale(LC_NUMERIC, "C");
-#else
+#elif defined(HAVE_USELOCALE)
saved_locale = uselocale(prof_locale);
+#else
+ saved_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
#endif
}
@@ -110,8 +119,10 @@ restore_locale( void )
#if defined(mingw32_HOST_OS)
_configthreadlocale(prof_locale_per_thread);
setlocale(LC_NUMERIC, saved_locale);
-#else
+#elif defined(HAVE_USELOCALE)
uselocale(saved_locale);
+#else
+ setlocale(LC_NUMERIC, saved_locale);
#endif
}